ruby-on-rails – Rails:嵌套资源冲突,如何根据被调用的路由对索引行为进行作用

前端之家收集整理的这篇文章主要介绍了ruby-on-rails – Rails:嵌套资源冲突,如何根据被调用的路由对索引行为进行作用前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
想像你有两条定义的路线:
map.resources articles
map.resources categories,:has_many => :articles

都可以通过助手/路径访问

articles_path # /articles
category_articles_path(1) # /category/1/articles

如果您访问/文章,则执行ArticleController中的索引操作.

如果你访问/ category / 1 / articles,ArticleController的索引操作也被执行.

那么,根据呼叫路由,有条件地仅选择作用域文章的最佳方法是什么?

#if coming from the nested resource route
@articles = Articles.find_by_category_id(params[:category_id])
#else
@articles = Articles.all

解决方法

您有两种选择,具体取决于您的逻辑和视图与范围的关系.
让我进一步解释.

第一个选择是确定您的控制器中的范围,如其他响应已经说明的.我通常设置一个@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]进行检查时重复.

如果您的观点,类别和无类别的观点非常相似,则此方法效果很好.但是,按照类别筛选的列表与没有类别的列表完全不同,会发生什么?这经常发生:您的类别部分提供了一些类别关注的小部件,而您的文章部分则是与文章相关的小部件和过滤器.此外,您的文章控制器有一些特殊的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管理.

这通常是我最喜欢的选择,因为通过额外的操作,您不必用大量的条件检查来混淆您的观点和控制器.

猜你在找的Ruby相关文章