0

マップを使用する場所は次のとおりです。

last_activities = report.deals.map do |deal|
  deal.activities.last
end

次に、「last_activities」で「where」を使用できるようにしたいのですが、last_activitiesは配列であるため、使用できません。私がやりたいのですが、できません。

fun_activities = last_activities.where(:type => "fun")

どうすればこれをRailsで実現できますか?

アップデート:

レポートhas_many
ディールディールbelongs_toレポート
ディールhas_manyアクティビティ
アクティビティbelongs_toディール

4

4 に答える 4

1

これを実現するには、次の 2 つの方法があります。

1) 配列を続けます。つまり、select で楽しいアクティビティを選択します。 fun_activities = last_activities.select { |a| a.type == "楽しい"}

2) 必要なアクティビティを直接選択する SQL ステートメントを定義するか、ActiveRecord クエリを使用して同じことを達成しようとします。これには、パフォーマンスが向上するか、すべてを配列にロードしないという利点があります。

于 2012-07-20T16:59:18.853 に答える
0

それらが少ない場合は、コメントで述べられているようにマップして選択することができます

all_last_activities = report.deals.map do |deal|
  deal.activities.last
end

fun_last_activities = all_last_activities.select do |act|
  act.type == "fun"
end

レコードがたくさんある場合は、次のようなクエリを使用することをお勧めします

all_last_activities_ids = report.deals.map do |deal|
  deal.activities.last.id
end

Activity.where(type: "fun").find(all_last_activities_ids)

またall_last_activities_ids、クエリから取得する必要がありますが、今はそれを行う方法を見つける時間がありません。しかし、グループ句が役立つはずです。

于 2012-07-20T17:05:45.603 に答える
0

AR / SQLクエリを使用する場合は、次の方法で実行できます。

Activity.joins(:deal).where(['deals.report_id = ? and activities.id in (select max(id) from activities group by deal_id)'], report.id)

これにより、元の質問で希望したような連鎖条件が可能になります。ただし、単純さと読みやすさのために、選択/拒否のアプローチを選択することをお勧めします。

于 2012-07-20T17:07:38.490 に答える
0

squeelを使用すると、生の SQL クエリを記述せずに Ruby でこれを簡単に表現できます。

max_ids_rel = Activity.group{deal_id}.select{max(id)}

Activity.joins{deal}.where{(deal.report_id == my{report.id}) && id.in(max_ids_rel)}

これにより、HargrimmTheBleak による提案と同様のサブセレクトが生成されます。生成されたテーブルとの結合も可能ですが、それにはさらにいくつかのグループ化ステートメントが必要であり、優れたクエリ アナライザーはとにかくこれを結合に変換できるはずなので、必要ありません。

于 2012-07-20T22:04:26.590 に答える