Rails嵌套资源和路由 - 如何分解控制器?

时间:2013-02-18 21:39:56

标签: ruby-on-rails-3 model-view-controller

我有以下型号:

  • 标签
  • TaggedPost(邮件和标签由has_many从中派生出来的关联:通过)

我有以下routes.rb文件:

resources :tags

resources :posts do
  resources :tags
end

因此,当我导航到/posts/4/tags时,这会将我射入Tag控制器的索引操作,并在参数数组中设置post_id值。凉。

我的问题是,现在我正在访问帖子下的嵌套标签资源,我是否还应该使用标签控制器?或者我应该设置一些其他控制器来处理此时标签的嵌套性质?否则,我必须在Tags控制器中构建额外的逻辑。当然可以这样做,但这是处理嵌套路由和资源的常用方法吗?我在Tags控制器的索引操作中的代码如下:

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. 如果是这样,应该如何命名和设置这些控制器?
  3. 如果您需要更多信息,请与我们联系。

2 个答案:

答案 0 :(得分:39)

我认为最好的解决方案是拆分控制器:

    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 :(得分:4)

您正在使用嵌套资源进行更改路由URL。您唯一需要做的就是确保将正确的ID(在您的案例中)传递给标签控制器。最常见的错误是无法找到*** ID。

如果您没有将配置文件路由嵌套到用户路由中,它将如下所示

  

domain.com/user/1

     

domain.com/profile/2

当您嵌套路线时,它将是

  

domain.com/user/1/profile/2

这就是它正在做的一切而没有别的。 您不需要其他控制器。做嵌套路由只是为了看起来。允许您的用户关注该关联。嵌套路由最重要的是确保将link_to设置为正确的路径。

不嵌套时:它将是

 user_path

 profile_path

当它嵌套时你需要使用

user_profile_path

rake routes是您的朋友,可以了解路线的变化情况。

希望它有所帮助。