0

私はこのようなクラスを持っています:

class Project < ActiveRecord::Base
  has_many :versions, :order => :position
end

コントローラー アクションで、プロジェクトのバージョンを照会する必要があります。私はプロジェクトIDを持っています。私は単に行うことができます

versions = Project.find(params[:project_id]).versions

ただし、これは最初に「projects」テーブルへのクエリを実行しますが、これは私の場合は不要です。私はそれをに変更することができました

versions = Version.find( :conditions => { :project_id => params[:project_id } )

(または同じ結果で動的ファインダーを使用します)

これは関連付けの追加の属性 (この場合は ":order => :position") を使用しないため、同じ例とまったく同じ結果を得たい場合は、次のように記述する必要があります。

versions = Version.find( :conditions => { :project_id => params[:project_id },
                         :order => :position )

ここでは、モデルで既に定義されている何か (「:order」オプション) を繰り返しているため、DRY ではなくなりました。

親オブジェクトをロードせずに、モデルで定義された関連付けを使用して従う方法はありますか? 現在も Rails 2.3.8 を使用しています。

4

2 に答える 2

0

順序付けには 1 つの default_scope を使用し、バージョン モデルでプロジェクトごとにバージョンを見つけるには別のスコープを使用することをお勧めします。

計画

class Project < ActiveRecord::Base
  has_many :versions
end

バージョン

 class Version < ActiveRecord::Base
   belongs_to :project
   named_scope :order_by_position, {:order => "position"} 
   named_scope :by_project_id, (lambda do |project_id| 
          {:conditions => ['project_id = ?', project_id]}
   end)
 end

次に、次を使用できます。

versions  = Version.by_project_id(params[:project_id])
于 2013-08-25T11:44:25.953 に答える
0

申し訳ありませんが、それはできないと確信しています - 少なくとも公開されている ActiveRecord API に従わないでください。

内部 ActiveRecord API を使用して関連付けオプションを検査する拡張機能を作成することもできますが、これはお勧めしません。

スコープを介していくつかの条件を再利用できますが、まだ Rails 2.3 を使用しているため、役に立ちません。

最後の例で書いたように、手動でバージョン インスタンスを取得するのが最善の策だと思います。

versions = Version.find( :conditions => { :project_id => params[:project_id },
                         :order => :position )

編集: Rails4 でできること:

次のように、モデルと関連付けの間でスコープを再利用および共有できます。

class Project < ActiveRecord::Base
  has_many :versions, -> { ordered }
end

class Version
  def self.ordered
    order(:position)
  end
end

versions = Version.find_by(:project_id, params[:project_id]).ordered

スコープが多く複雑になればなるほど、このアプローチはより有用になります。

于 2013-08-25T11:19:13.753 に答える