Rails map.resources 与 has_many :through 不起作用?

发布于 2024-07-09 05:53:44 字数 1398 浏览 6 评论 0原文

我有三个(相关)模型,指定如下:

class User < ActiveRecord::Base
  has_many :posts
  has_many :comments
  has_many :comments_received, :through => :posts, :source => :comments
end

class Post < ActiveRecord::Base
  belongs_to :user
  has_many :comments
end

class Comment < ActiveRecord::Base
  belongs_to :user
  belongs_to :post
end

我希望能够通过路线引用 user 的所有 comments_received - 假设它是用于批量批准所有帖子的评论。 (请注意,您还可以获取用户发表的评论,但用户无法评论自己的帖子,因此评论 > 通过 post 是不同且互斥的)。 从逻辑上讲,这应该适用于:

map.resources :users, :has_many => [:posts, :comments, :comments_received]

这应该给我

user_posts_path
user_comments_path
user_comments_received_path

前两个有效的路线,最后一个无效。 我已经尝试过在 comments_received 中没有使用 _ ,但没有成功。 我正在寻找一个 URL,就像

http://some_domain.com/users/123/comments_received

我也尝试过嵌套它一样,但也许我做错了。 在这种情况下,我认为地图将是:

map.resources :users do |user|
  user.resources :comments
  user.resources :posts, :has_many => :comments
end

然后网址可能是:

http://some_domain.com/users/123/posts/comments

也许这是正确的方法,但我的语法错误?

我是否以错误的方式思考这个问题? 对我来说,我应该能够获得添加到所有用户帖子中的所有评论的页面,这似乎是合理的。

感谢您的帮助!

I've got three (relevant) models, specified like this:

class User < ActiveRecord::Base
  has_many :posts
  has_many :comments
  has_many :comments_received, :through => :posts, :source => :comments
end

class Post < ActiveRecord::Base
  belongs_to :user
  has_many :comments
end

class Comment < ActiveRecord::Base
  belongs_to :user
  belongs_to :post
end

I'd like to be able to reference all the comments_received for a user with a route - let's say it's for batch approval of comments on all posts. (note that you can also get comments made by the user, but users can't comment on their own posts, so the comments through a post are different and mutually exclusive). Logically, this should work with:

map.resources :users, :has_many => [:posts, :comments, :comments_received]

This should give me routes of

user_posts_path
user_comments_path
user_comments_received_path

The first two work, the last one doesn't. I've tried it without the _ in comments_received to no avail. I'm looking to get a URL like

http://some_domain.com/users/123/comments_received

I've also tried nesting it, but maybe I'm doing that wrong. In that case, I'd think the map would be:

map.resources :users do |user|
  user.resources :comments
  user.resources :posts, :has_many => :comments
end

and then the url might be:

http://some_domain.com/users/123/posts/comments

Maybe this is the right way to do it, but I have the syntax wrong?

Am I thinking about this the wrong way? It seems reasonable to me that I should be able to get a page of all the comments added to all of a user's posts.

Thanks for your help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

花心好男孩 2024-07-16 05:53:44

尽管定义资源和模型关系的语法相似,但您不应该误以为资源映射到模型。 阅读David Black 所说的

您遇到的问题是您生成的路线。 使用像这样的嵌套语法:

map.resources :users do |user|
  user.resources :posts
  user.resources :comments
  user.resources :comments_received
end

然后运行'rake paths',给我(在其他东西的负载中!):

                       users GET /users                              {:action=>"index", :controller=>"users"}
                  user_posts GET /users/:user_id/posts               {:action=>"index", :controller=>"posts"}
               user_comments GET /users/:user_id/comments            {:action=>"index", :controller=>"comments"}
user_comments_received_index GET /users/:user_id/comments_received   {:action=>"index", :controller=>"comments_received"}

所以看来rails正在将_index添加到comments_received路由的末尾。 我承认我不知道为什么(与其他评论路线冲突有关?)但它解释了你的问题。

更好的替代方法可能是在评论资源上定义一个收集操作,如下所示:

map.resources :users do |user|
  user.resources :posts
  user.resources :comments, :collection => {:received => :get}
end

这将为您提供以下路由:

                 users GET /users                             {:action=>"index", :controller=>"users"}
            user_posts GET /users/:user_id/posts              {:action=>"index", :controller=>"posts"}
         user_comments GET /users/:user_id/comments           {:action=>"index", :controller=>"comments"} 
received_user_comments GET /users/:user_id/comments/received  {:action=>"received", :controller=>"comments"}

注意:收到的操作现在位于评论控制器上

Although the syntax to deinfe resource and model relationship is similar, you shouldn't be fooled into thinking that a resource maps to a model. Read what David Black has to say.

The problem you're having is with the routes you're generating. Using the nested syntax like so:

map.resources :users do |user|
  user.resources :posts
  user.resources :comments
  user.resources :comments_received
end

And then running 'rake routes', gives me (amongst loads of other stuff!):

                       users GET /users                              {:action=>"index", :controller=>"users"}
                  user_posts GET /users/:user_id/posts               {:action=>"index", :controller=>"posts"}
               user_comments GET /users/:user_id/comments            {:action=>"index", :controller=>"comments"}
user_comments_received_index GET /users/:user_id/comments_received   {:action=>"index", :controller=>"comments_received"}

So it appears that rails is adding _index to the end of the comments_received route. I'll admit I don't know why (something to do with clashing with the other comments route?) but it explains your problem.

An nicer alternative might be to define a collection action on your comments resource, like so:

map.resources :users do |user|
  user.resources :posts
  user.resources :comments, :collection => {:received => :get}
end

This will give you the following routes:

                 users GET /users                             {:action=>"index", :controller=>"users"}
            user_posts GET /users/:user_id/posts              {:action=>"index", :controller=>"posts"}
         user_comments GET /users/:user_id/comments           {:action=>"index", :controller=>"comments"} 
received_user_comments GET /users/:user_id/comments/received  {:action=>"received", :controller=>"comments"}

Note: the received action is now on the comments controller

柠檬 2024-07-16 05:53:44

我必须承认,我对变量名称有点困惑,但首先,我很惊讶你的 has_many :through 能够按照它的定义方式工作。 暂时搁置路线,模型的表现是否符合您的预期?

其次,这就是变量名真正发挥作用的地方,路由对复数有一定的依赖性,因此您的 foos bar 和 bazs 可能是问题的原因,或者可能隐藏了问题。 无论如何,你绝对可以写这样的东西:

map.resources :users do |user|
  user.resources :awards
  user.resources :contest_entries do |contest_entry|
    contest_entry.resources :awards
  end
end

我相信这会给你:

user_path, user_awards_path, user_contest_entry_path, and user_contest_entry_awards_path.

我不确定这是否真的回答了你的问题,如果你改变了 foo,它可能有助于更清楚地了解这里发生的情况,酒吧,并巴兹更接近真实情况。

I have to confess, I'm a little confused by the variable names, but first off, I'm surprised your has_many :through works at all the way it's defined. Do the models behave as you expect, setting aside the routes for a second?

Second, and this is where the variable names really come into play, the routes have some dependencies on pluralization, so your foos bars and bazs might either be a cause of the problem, or might be hiding the problem. In any event, you can definitely write something like this:

map.resources :users do |user|
  user.resources :awards
  user.resources :contest_entries do |contest_entry|
    contest_entry.resources :awards
  end
end

which I believe would give you:

user_path, user_awards_path, user_contest_entry_path, and user_contest_entry_awards_path.

I'm not sure if this really answers your question, and it might help to get a clearer picture of what's going on here if you changed foo, bar, and baz to something closer to the real situation.

方觉久 2024-07-16 05:53:44

一个快速而肮脏的解决方案是将一个自定义方法(例如 getusercomments)添加到您的用户控制器中,该方法将返回所有评论:

def getusercomments
@user = User.find(params[:id])
@comments = @user.posts.comments
end

然后将此方法添加到您的用户路由中:

map.resources :users, :member => { :getusercomments => :get }

之后您应该能够调用以下命令获取用户的所有评论:

http://some_domain.com/users/123/getusercomments

A quick-n-dirty solution would be to add a custom method (e.g. getusercomments) to your users-controller that would return all the comments:

def getusercomments
@user = User.find(params[:id])
@comments = @user.posts.comments
end

Then add this method to your users-route:

map.resources :users, :member => { :getusercomments => :get }

Afterwards you should be able to call the following to get all comments of a user:

http://some_domain.com/users/123/getusercomments
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文