0

2 つのオブジェクト間に関係があります。次のように言いましょう: Model1 has_many Model2 (それはあまり重要ではありません)

そして、結果の一部を除外したいとします。

a = Model1.find(123) 
b = a.model2

そして今、たとえば、EVENレコードのみを(IDで)選択したい

次のようにb.select {|x| x.id % 2 == 0}すると、期待どおりにすべての偶数レコードが返されます。また、追加のデータベース クエリは作成されません。

しかし、Model2 でクラス メソッドを定義すると、次のようになります。

def self.even_records
   select {|x| x.id % 2 == 0}
end

次に、何らかの魔法の理由で、データベースに追加のクエリを作成します。これは、「b」変数を再インスタンス化したように見えます (リレーションを再ロードします)。

Model2 Load (0.4ms)  SELECT `model2`.* FROM `model2` WHERE `model2`.`model1_id` = 123

なぜそう振る舞うのですか?修正する方法はありますか?

after_findPS私は、どのモデルでも定義されているような、怪しげなコールバックはありません。

4

2 に答える 2

1

これら 2 つの基本的な違いは、配列である b に対して select メソッドを呼び出すと、列挙可能なメソッドselectが呼び出されることです。

b.select {|x| x.id % 2 == 0} 

メソッドを記述すると、activerecord クエリ インターフェイスの select メソッドが呼び出されます。

def self.even_records
   select {|x| x.id % 2 == 0}
end

ところで、Ruby にはeven?や などのメソッドがodd?あるため、直接呼び出すことができます。

even_records = b.select{|x| x.id.even?}
odd_records = b.select{|x| x.id.odd? }

Edit:私はあなたのための簡単な解決策を見つけました。Model2以下のようにモデルでスコープを定義できます。

scope :even_records, -> { where ('id % 2 == 0') }

そして今、あなたが電話するなら:

Model2.even_records

あなたのeven_recordsがあります。ありがとう

于 2013-10-01T08:40:11.873 に答える