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管理. 这通常是我最喜欢的选择,因为通过额外的操作,您不必用大量的条件检查来混淆您的观点和控制器. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |