0

スコープまたはクラス メソッドでモデルのメソッドを使用する方法はありますか?

連絡先クラスにこれら 2 つのメソッドがあり、連絡先がアクティブかどうかを定義します

def active
 return no_of_activities_last_year > 0 ? true : false
end


def no_of_activities_last_year
  time_range = (Time.now - 1.year)..Time.now
  activities.where(:updated_at => time_range).count
end

次に、スコープまたはクラスメソッドのいずれかで、次のようなすべてのアクティブな連絡先を返すことができるようにしたいと思います。

scope :active_contacts, lambda {where(:active => true)} 

また

def self.active_contacts
 where(:active => true)
end

しかし、アクティブはデータベースの一部ではないため、機能しません。

これを実現できる賢い方法はありますか?そして、他のスコープと組み合わせることができる方法で望ましいですか?

4

1 に答える 1

1

私の知る限り、ありません。ActiveRecord の背後にある全体的なアイデアは、データベースへのクエリを作成することです。データベースに「このルビ コード ロジックが true であるすべてのレコードを取得する」ように指示することはできませんが、データベースに「この基準に基づくすべてのレコードを取得する」ように指示することはできます。

そのため、内部選択を引き続き使用できます。より良い方法があるかもしれませんが、次のことができます。

raw_data = User.connection.execute("select user_id from (SELECT count(*) as qty, user_id FROM activities f2 WHERE user_id is not null AND created_at > DATE_SUB(NOW(), INTERVAL 1 WEEK) GROUP BY user_id HAVING qty > 1) as f1")
User.where("id in (?)", raw_data.to_a.flatten)

これは最もクリーンなソリューションではありませんが、高速であり、他のクエリを作成する方法についてのアイデアを提供します。

生の SQL を書きたくないが正しい方法で書きたい場合は、いつでも Arel について学習したり、Squeel を使用したりできます。

別の方法として、すべてのデータを取得してから ruby​​ コードでフィルター処理することもできますが、SQL エンジンに結果をフィルター処理させるよりも効率が悪くなります。

于 2012-12-12T11:05:17.613 に答える