ルビー・オン・レールでは、すべてhas_many :widgets
メソッドはobject.widgets
メソッドとobject.widget_ids
メソッドの両方を生成します。名前付きスコープ内の要素のIDを取得する
後者の方法は、ActiveRecordオブジェクトの作成をバイパスし、はるかに高速なクエリを実行するため、非常に便利です。クエリの速度は:select
オプションを使用することで改善できますが、整数ではなくオブジェクトを生成する際にはもっと多くのメモリが割り当てられます。
User has_many :historical_sessions:
>> Benchmark.measure { User.find(4).historical_sessions.map(&:id) }
HistoricalSession Load (131.0ms) SELECT * FROM `historical_sessions` WHERE (`historical_sessions`.user_id = 4)
=> #<Benchmark::Tms:0xbe805c0 @cutime=0.0, @label="", @total=1.996, @stime=0.0150000000000006, @real=2.09599995613098, @utime=1.981, @cstime=0.0>
(2.1 seconds)
>> Benchmark.measure { User.find(4).historical_session_ids }
HistoricalSession Load (34.0ms) SELECT `historical_sessions`.id FROM `historical_sessions` WHERE (`historical_sessions`.user_id = 4)
=> #<Benchmark::Tms:0x11e6cd94 @cutime=0.0, @label="", @total=1.529, @stime=0.032, @real=1.55099987983704, @utime=1.497, @cstime=0.0>
(1.6 seconds)
例えば
(結果セットが67353個のオブジェクトである)
はnamed_scopesを使用した場合と同じ動作が起こる持っているそこの方法ですか?例えば
、
User named_scope :recent
User.recent (Exists)
User.recent_ids (Does not exist)
私は現在、名前付き範囲の結果セット内のオブジェクトのIDを取得する方法である: HistoricalSession.recent.map(&:ID)。これは基本的に上記の後者の例で行われているのと似ており、明らかに効率的ではありません。私が最後に必要なのは、IDの配列ですが、私はHistoricalSessionオブジェクト全体を構築したくありません。
別の実装では、新しい.findメソッドを使用できます。たとえば、HistoricalSession.recent.find_attributes(:id)です。このメソッドは、selectステートメントを置き換えて指定された値のみを選択し、ActiveRecordオブジェクトの作成を短絡して配列を返します。
提案がありますか?これは簡単なプラグインで書くことができますか?