У вас есть два варианта здесь, в зависимости от того, насколько ваша логика и ваш взгляд связаны с областью действия.
Позвольте мне объяснить подробнее.
Первый выбор - определить область действия вашего контроллера, как уже объяснено другими ответами. Я обычно устанавливаю переменную @scope, чтобы получить некоторые дополнительные преимущества в моих шаблонах.
class Articles
before_filter :determine_scope
def index
@articles = @scope.all
# ...
end
protected
def determine_scope
@scope = if params[:category_id]
Category.find(params[:category_id]).articles
else
Article
end
end
end
Причина переменной @scope заключается в том, что вам может потребоваться узнать объем вашего запроса за пределами одного действия. Предположим, вы хотите отобразить количество записей в вашем представлении. Вы должны знать, фильтруете ли вы по категории или нет. В этом случае вам просто нужно позвонить @scope.count
или @scope.my_named_scope.count
вместо того, чтобы повторять каждый раз проверку params[:category_id]
.
Этот подход хорошо работает, если ваши взгляды, с категорией и без категории, очень похожи. Но что происходит, когда список, отфильтрованный по категории, полностью отличается от списка без категории? Это происходит довольно часто: в разделе вашей категории есть некоторые виджеты, ориентированные на категории, а в разделе статей - виджеты и фильтры, связанные со статьей. Кроме того, в вашем контроллере Article есть несколько специальных before_filters, которые вы, возможно, захотите использовать, но вам не нужно их использовать, когда список статей принадлежит категории.
В этом случае вы можете разделить действия.
map.resources articles
map.resources categories, :collection => { :articles => :get }
articles_path # /articles and ArticlesController#index
category_articles_path(1) # /category/1/articles and CategoriesController#articles
Теперь список, отфильтрованный по категориям, управляется CategoriesController
, и он наследует все фильтры, макеты, настройки контроллера, а нефильтрованный список управляется ArticlesController
.
Обычно это мой любимый выбор, потому что с дополнительным действием вам не нужно загромождать свои представления и контроллеры тоннами условных проверок.