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

上記の例では、ユーザーに関連付けられている最近のブログ投稿を見つける方法が 2 つあります。Post.find を呼び出して author_id を渡すか、self.posts.find を呼び出すことができ、著者 ID を渡す必要はありません。これは、後者の場合、ユーザー オブジェクトの主キーと、このユーザーに関連付けられた has_many :posts に基づいて、self.posts が既に制限されているためだと思います。これは、この場合の利点です。なぜなら、author_id を引数として渡すという手間をかける必要がないからです。しかし、作成者ごとにクエリを制限する必要がなければ、これを行うために all_recent_posts_on_self を作成することは可能でしょうか?

私が話しているのは、このメソッドに相当するものです(:conditions を省略しています):

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

ただし、 Post.find の代わりに self.posts.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 モデルに制限したくない場合に使用する必要があります。結局のところ、User オブジェクトの posts() メソッドは、Post.find(:all, :conditions => ['author_id', self.id]) への (キャッシュされた) 呼び出しと実質的に同じ便利なものに過ぎませんでした。

于 2009-05-23T23:57:22.610 に答える