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

Les*_*ody 21 model-view-controller ruby-on-rails-3

我有以下型号:

  • 岗位
  • 标签
  • TaggedPost(Post和Tag通过has_many从中派生出他们的关联:through)

我有以下routes.rb文件:

resources :tags

resources :posts do
  resources :tags
end
Run Code Online (Sandbox Code Playgroud)

因此,当我导航到,比如说,/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
Run Code Online (Sandbox Code Playgroud)

我可以看到这个控制器中的代码越来越大,因为我计划将许多额外的资源与标记资源相关联.关于如何打破这个的想法?

问题摘要:

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

如果您需要更多信息,请与我们联系.

Iaz*_*zel 39

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

    resources :tags

    resources :posts do
      resources :tags, controller: 'post_tags'
    end
Run Code Online (Sandbox Code Playgroud)

然后你有3个控制器.或者,您可以从TagsController继承PostTagsController来执行以下操作:

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

如果差异只是标签的检索,您可以:

    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
Run Code Online (Sandbox Code Playgroud)

使用该方法并简单地覆盖继承控制器中的标记;)


小智 5

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

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

domain.com/user/1

domain.com/profile/2

当您嵌套路线时

domain.com/user/1/profile/2

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

不嵌套时:它会

 user_path
Run Code Online (Sandbox Code Playgroud)

 profile_path
Run Code Online (Sandbox Code Playgroud)

当它嵌套时你需要使用

user_profile_path
Run Code Online (Sandbox Code Playgroud)

rake routes 是你的朋友,了解路线是如何变化的.

希望能帮助到你.

  • 在这个投票中投入一些辛苦赚取的积分.请,请添加嵌套控制器. (3认同)