1

扩展下面的 recent_posts_on_self,我想添加一个 all_recent_posts_on_self 方法,但我不确定是否可以使用语法 self.posts.find。另一方面, all_recent_posts_on_class 似乎很简单。

class User < ActiveRecord::Base
  has_many :posts, :class_name => "Post" , :foreign_key => "author_id"
  has_many :comments, :class_name => "Comment", :foreign_key => "author_id"

  def recent_posts_on_class
    Post.find(  :all, :conditions => ['author_id = ?', self.id],
                :order => 'created_at asc', :limit => 5)
  end

  def recent_posts_on_self
    self.posts.find(:all, :order => 'created_at ASC', :limit => 5)
  end
end

在上面的示例中,我有两种方法可以找到与用户关联的最近的博客文章。我可以调用 Post.find 并将 author_id 传递给它,或者我可以调用 self.posts.find 而我不需要传递作者 ID。我认为这是因为在后一种情况下,self.posts 已经根据用户对象的主键和与该用户关联的 has_many :posts 进行了限制。在这种情况下,这是一个优势,因为我不需要麻烦地将 author_id 作为参数传递。但是,如果我不需要按作者限制查询,是否可以创建一个 all_recent_posts_on_self 来执行此操作?

我在说的是这种方法的等价物(它省略了:条件):

  def all_recent_posts_on_class
    Post.find(:all, :order => 'created_at asc', :limit => 5)
  end

但使用 self.posts.find 而不是 Post.find

  def all_recent_posts_on_self
    self.posts.find(...)
  end

还:

即使可以使用 self.posts.find 来做到这一点,使用 Post.find 是否“更好”?

4

2 回答 2

4

这并不完全是您所要求的,但我认为这有助于了解和遵循常见模式有助于避免复杂或令人困惑的实现。

执行此操作的“Rails 方式”是使用命名范围:

class Post < ActiveRecord::Base
  belongs_to :user
  named_scope :recent, :order => 'created_at desc', :limit => 5
end

class User < ActiveRecord::Base
  has_many :posts
end

没有比这更具声明性和易于阅读的了:

user.posts.recent # 5 most recent posts by the user
Post.recent # 5 most recent posts globally
于 2009-05-24T01:34:10.323 回答
1

我不确定您为什么要使用 self.posts.find(..) 来查找其他作者的帖子。这个习惯用法专门用于查找与特定实例关联的对象的子集。

Post.find() 是当您不想限制特定用户模型时应该使用的。毕竟,User 对象上的 posts() 方法只是一种便利,它实际上与对 Post.find(:all, :conditions => ['author_id', self.id]) 的(缓存)调用相同。

于 2009-05-23T23:57:22.610 回答