25

我有以下型号:

  • 邮政
  • 标签
  • TaggedPost(Post 和 Tag 通过 has_many :through 从中获得关联)

我有以下routes.rb文件:

resources :tags

resources :posts do
  resources :tags
end

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

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

标签控制器.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. If a resource is nested, should the nested resource be going through a different controller representing the nested nature of the resource? This is opposed to going through the normal controller as I am in the code example that I provided.
  2. If so, how should these controllers be named and setup?

Let me know if you need more information.

4

2 回答 2

50

I think the best solution is to split up controllers:

    resources :tags

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

And then you have 3 controllers. Optionally, you can inherit PostTagsController from TagsController to do something like:

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

If the difference is only the retrieval of tags, you can:

    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

Use that methods and simply override tags in the inheriting controllers ;)

于 2013-02-18T23:30:43.563 回答
6

All you are doing with nested resources is changing the routing URL. Only thing you would have to do is make sure you are passing the proper id (in your case post)to the tag controller. Most common error is the Can't Find *** ID.

If you don't nest a profile route into a user route it would look like this

domain.com/user/1

domain.com/profile/2

When you nest the routes it would be

domain.com/user/1/profile/2

That is all that it is doing and nothing else. You don't need additional controllers. Doing nested routing is just for looks. allowing your user to follow the association. The most important thing about nesting routes is that you make sure you make the link_to's to the right path.

When not nested: it would be

 user_path

and

 profile_path

when it is nested you would need to use

user_profile_path

rake routes is your friend to find out how the routes have changed.

Hope it helps.

于 2013-02-18T23:00:33.970 回答