3

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

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_receiveda user- 假设它是为了批量批准所有帖子的评论。(请注意,您也可以comments通过 获得user,但用户无法对自己的帖子发表评论,因此comments通过 apost是不同且互斥的)。从逻辑上讲,这应该适用于:

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添加到所有用户帖子的页面,这似乎是合理的。

谢谢你的帮助!

4

3 回答 3

2

尽管 deinfe 资源和模型关系的语法相似,但您不应该误以为资源映射到模型。阅读大卫布莱克所说的话

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

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 似乎将 _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"}

注意:收到的动作现在在评论控制器上

于 2009-04-30T08:39:55.707 回答
0

我必须承认,我对变量名有点困惑,但首先,我很惊讶你的 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、bar 和 baz 更改为更接近真实情况的内容,这可能有助于更清楚地了解这里发生的情况。

于 2008-11-11T23:03:46.403 回答
0

Quick-n-dirty 解决方案是向您的用户控制器添加一个自定义方法(例如 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
于 2008-11-24T23:36:20.507 回答