2013-02-18 135 views
17

我有以下型号:Rails嵌套的资源和路由 - 如何分解控制器?

  • 标签
  • TaggedPost(从邮政和标签,标签的has_many获得其关联:通过)

和我有以下routes.rb文件:

resources :tags 

resources :posts do 
    resources :tags 
end 

所以当我n例如/posts/4/tags,这将使我在参数数组中设置post_id值的情况下,将我带入标签控制器的索引操作。凉。

虽然我的问题是,现在我正在访问帖子下的嵌套标签资源,我应该点击标签控制器吗?或者我应该设置一些其他控制器来处理此时标签的嵌套特性?否则,我必须在标签控制器中增加额外的逻辑。这当然可以完成,但这是处理嵌套路由和资源的常见方式吗?我在为标签控制器index操作的代码如下:

TagsController.rb

def index 
    if params[:post_id] && @post = Post.find_by_id(params[:post_id]) 
    @tags = Post.find_by_id(params[:post_id]).tags 
    else 
    @tags = Tag.order(:name) 
    end 
    respond_to do |format| 
    format.html 
    format.json {render json: @tags.tokens(params[:q]) } 
    end 
end 

我可以看到在这个控制器的代码变得越来越大,因为我计划了很多额外的与标签资源相关联的资源。如何解决这个问题的想法?

总结的问题:

  1. 如果资源被嵌套,如果嵌套的资源是通过代表的资源的嵌套性质不同的控制器去?这与我提供的代码示例中的正常控制器相反。
  2. 如果是这样,这些控制器应该如何命名和设置?

让我知道你是否需要更多信息。

回答

4

所有你正在做的嵌套资源正在改变路由URL。唯一需要做的事情是确保将正确的身份证(在您的个人信息中)传递给标签控制器。最常见的错误是无法找到*** ID。

,如果你不嵌套的轮廓路径到用户的路线就应该是这样的

domain.com/user/1

domain.com/profile/2

当你巢路线这将是

domain.com/user/1/profile/2

这是所有它在做什么。没有其他的。你不需要额外的控制器。做嵌套路由只是为了看起来。让您的用户关注关联。关于嵌套路线最重要的事情是,你要确保你的link_to是正确的路径。

没有嵌套时:这将是user_path和profile_path

当它被嵌套,你将需要使用user_profile_path。

耙路是您的朋友,了解路线如何变化。

希望它有帮助。

+0

这实际上回答了我的问题的核心......我想除此之外的物流真的取决于我强迫组织的需求。 – 2013-02-18 23:15:31

+0

请为了你未来的同事(和你自己!),请阅读@lazel答案! – gfd 2016-12-13 16:00:27

+0

打算在这个投票中花费一些辛苦赚取的点数。请添加嵌套控制器。 – Drenmi 2017-11-26 14:08:55

29

我认为最好的办法是分裂控制器:

resources :tags 

    resources :posts do 
     resources :tags, controller: 'PostTagsController' 
    end 

然后你有3个控制器。或者,你可以从TagsController继承 PostTagsController做这样的事情:

class PostTagsController < TagsController 
     def index 
      @tags = Post.find(params[:post_id]).tags 
      super 
     end 
    end 

如果差别仅仅是标签的检索,您可以:

class TagsController < ApplicationController 
     def tags 
      Tag.all 
     end 

     def tag 
      tags.find params[:id] 
     end 

     def index 
      @tags = tags 
      # ... 
     end 
     # ... 
    end 

    class PostTagsController < TagsController 
     def tags 
      Product.find(params[:product_id]).tags 
     end 
    end 

使用方法和简单地重写标签在继承控制器;)

+1

这个答案是更清洁,更容易理解任何即将到来的同事恕我直言。我知道Rails是关于DRY的,但在这种情况下,OP说'我计划将许多额外的资源与标签资源相关联,以便区分每个关联可能会很有帮助... – gfd 2016-12-13 15:51:30

+1

现在在控制器选项中我们应该有'post_tags'。 http://guides.rubyonrails.org/routing.html#specifying-a-controller-to-use – 2018-01-08 11:04:30