我有三个(相关的)模型,如下所示:
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
我希望能够引用带有路线的comments_received
的所有user
- 让我们说这是批量批准所有帖子的评论。 (请注意,您也可以comments
获取user
,但用户无法对自己的帖子发表评论,因此comments
到post
是map.resources :users, :has_many => [:posts, :comments, :comments_received]
不同且互相排斥的)。从逻辑上讲,这应该适用于:
user_posts_path
user_comments_path
user_comments_received_path
这应该给我
的路线_
前两个工作,最后一个不工作。我试过没有comments_received
中的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
然后网址可能是:
comments
也许这是正确的方法,但我的语法错了?
我是否以错误的方式思考这个问题?对我而言,我应该能够将所有{{1}}的页面添加到用户的所有帖子中,这似乎是合理的。
感谢您的帮助!
答案 0 :(得分:2)
尽管deinfe资源和模型关系的语法类似,但您不应该误以为资源映射到模型。阅读David Black has to say。
您遇到的问题是您正在生成的路线。使用嵌套语法如下:
map.resources :users do |user|
user.resources :posts
user.resources :comments
user.resources :comments_received
end
然后运行'rake 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"}
user_comments_received_index GET /users/:user_id/comments_received {:action=>"index", :controller=>"comments_received"}
因此看起来rails正在将comments_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"}
注意:收到的操作现在位于评论控制器上
答案 1 :(得分:0)
我必须承认,我对变量名称感到有些困惑,但首先,我很惊讶你的has_many:通过它所定义的所有方式工作。模型是否按预期运行,将路线搁置一秒?
其次,这就是变量名真正起作用的地方,路由对复数有一些依赖性,所以你的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,bar和baz变成更接近实际情况的东西,这可能有助于更清楚地了解这里发生了什么。
答案 2 :(得分:0)
快速弄脏的解决方案是向用户控制器添加一个自定义方法(例如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