2012-03-16 3 views
1

Могу ли я использовать оператор if в своем контроллере или это плохая практика?Если оператор Rails Controller?

В обоих моих создают и разрушающих действий для TracksController, я хочу сделать что-то вроде этого:

if Product 
@product = Product.find(params[:product_id]) 
@track = @product.tracks.create(params[:track]) 

eslif Release 
@Release = Release.find(params[:release_id]) 
@track = @release.tracks.create(params[:track]) 
end 

Есть ли лучший способ сделать это?

ответ

1

Я бы пойти дальше и предложить более DRY подхода к before_filter:

class TracksController < ApplicationController 
    before_filter :get_track_parent, only: [ :create, :destroy ] 

    def create 
    @track = @parent.tracks.create(params[:track]) 
    ... 
    redirect_to @parent 
    end 

    private 

    def get_track_parent 
    if params[:product_id].present? 
     @parent = Product.find(params[:product_id]) 
    elsif params[:release_id].present? 
     @parent = Release.find(params[:release_id]) 
    end 
    end 
end 

Я родитель, потому что мы получили контекст для модели отношений, но я предполагаю, что есть лучший термин для описания общности между выпуском и обработкой товара.

+0

Спасибо, это имеет большой смысл, я буду реализовывать это сейчас. – Raoot

+0

Кажется, что это хорошо работает, за исключением того, что у меня возникают проблемы с перенаправлением с использованием этого подхода. Статусы if и elsif содержат «redirect_to product_path (@product)» или «redirect_to release_path (@release)». Каков наилучший способ добавить их сухим способом? – Raoot

+0

с этими методами вам просто нужно указать переменную redirect_to так: 'redirect_to @ parent' – Vapire

3

Я хотел бы сделать это с помощью before_filter обратного вызова:

class TracksController < AC 
    before_filter :ensure_track, :only => [ :create, :destroy ] 

    private 

    def ensure_track 
    if Product 
     @product = Product.find(params[:product_id]) 
     @track = @product.tracks.create(params[:track]) 
    elsif Release 
     @release = Release.find(params[:release_id]) 
     @track = @release.tracks.create(params[:track]) 
    end 
    end 
end 

Так что с этой установкой он гарантировал, что у вас есть @track переменную экземпляра в вашем создавать и уничтожать методы, вызвать ensure_track получает вызывается перед этими двумя методами ,

Я не уверен, что если логика, которую вы применяете, имеет смысл ... Почему вы хотите проверить, существует ли константа с именем Product, а если нет константы с именем Release? Может быть, вопрос должен быть, если присутствует params[:product_id] или params[:release_id] !?

Но это другой вопрос :)

UPDATE: См Rails Action Controller Guide для фильтров.

+0

Спасибо. Не уверен, что я это понимаю, но я попробую. Что касается логики; У меня есть модели Release & Product, в которых могут быть треки, каждый из которых записан в Release_Tracks и в ассоциациях/таблицах Product_Tracks HABTM. Теперь у меня так далеко, я действительно задаюсь вопросом, должен ли я использовать другой подход и использовать ассоциацию Polymorphic? – Raoot

+0

Я вижу ... Ну, я думаю, что полиморфное отношение имеет смысл здесь. Но ваш вышеприведенный if-statement всегда по умолчанию имеет значение true, потому что всегда существует константа с именем 'Product' в вашем пространстве имен, поэтому она никогда не войдет в путь elsif ... – Vapire

+0

А, я понимаю, как работают фильтры Теперь. Я только что вспомнил, почему раньше я не использовал полиморфную ассоциацию; когда продукт создается, он наследует дорожки, связанные с его родительским выпуском, и мне нужно поддерживать возможность изменения списка треков на уровне продукта и добавлять дополнительные «бонусные» треки, которые отображаются только на отдельном продукте. Итак, я вернусь к мысли, что оригинальный подход - это то, что мне нужно. Мне просто нужно сделать инструкцию if. – Raoot