Problem と ProblemSet という 2 つの ActiveRecord モデルがあるとします。
@problem_set オブジェクトがあり、特定のタイトル属性に問題があるかどうかを確認したいとします。
あなたは言えた:
@problem_set.problems.where(:title => "Adding Numbers").any?
true
これは、最適な SQL を実行してを返します。
SELECT COUNT(*) FROM "problems" INNER JOIN "problem_sets_problems" ON "problems"."id" = "problem_sets_problems"."problem_id" WHERE "problem_sets_problems"."problem_set_id" = 1 AND "problems"."title" = 'Adding Numbers'
ただし、@problem_set がメモリ内にある場合、つまり @problem_set を次のように取得した場合:
@problem_set = ProblemSet.new()
@problem_set.problems << Problem.new(:title = "Adding Numbers")
そうすると、問題を見つけることができなくなります (つまり、false が返されます!)。これは、次の SQL が実行されるためです。
SELECT COUNT(*) FROM "problems" INNER JOIN "problem_sets_problems" ON "problems"."id" = "problem_sets_problems"."problem_id" WHERE "problem_sets_problems"."problem_set_id" IS NULL AND "problems"."title" = 'Adding Numbers'
永続オブジェクトとメモリ内オブジェクトの両方に対してチェックを正しく実行する方法は次のとおりです。
@problem_set.problems.map(&:title).include? "Adding Numbers"
どちらの場合も正しく返さtrue
れます。ただし、永続オブジェクトの場合は、最適化されていない SQL (すべての問題を取得します) を実行します。
SELECT "problems".* FROM "problems" INNER JOIN "problem_sets_problems" ON "problems"."id" = "problem_sets_problems"."problem_id" WHERE "problem_sets_problems"."problem_set_id" = 1
質問: 最適な SQL コードを実行しながら、同じコードを使用して永続オブジェクトとメモリ内オブジェクトの両方をチェックする方法はありますか?
オブジェクトの永続性をチェックするソリューションが許可されていることに注意してください (ただし、コレクションの汚れをチェックする方法はわかりません)。ただし、永続オブジェクトが変更された場合でも機能するはずです (つまり、関連付けコレクションの属性がダーティになり、SQL クエリの結果が古くなっている可能性があります)。