(下のスキーマ画像の例を参照)
テーブルの&フィールドとともにusers
、フィールドを使用して、テーブルから 1 人のユーザーをクエリしようとしています。結果には、見つかったユーザー (存在する場合) と、アプリケーション ( &フィールドを使用して参照) および関連データが含まれます。email
id
key
applications
key
id
applications_users
この操作を実行するために SQL を手動で簡単に記述できます。
SELECT
"users".*,
"applications_users"."scopes",
"jwt_applications".*
FROM
"users"
INNER JOIN
"applications_users" ON "applications_users"."user_id" = "users"."id"
INNER JOIN
"jwt_applications" ON "jwt_applications"."id" = "applications_users"."application_id"
WHERE
"users"."email" = 'rainbows@unicorns.net'
AND "jwt_applications"."id" = '01daafc9-2169-4c78-83e9-37ac0a473e3d'
AND "jwt_applications"."key" = 'follow_the_rainbow'
LIMIT 1
ただし、ActiveRecordを使用すると、一生クエリを正しく取得できません。
これらは、これまでに行った失敗した試みです。
user = User.where(email: args[:username]).joins(:applications).merge(
JwtApplication.where(id: args[:application][:id], key: args[:application][:key])
).take!
これはユーザーを正しく取得しますが、アクセスしようとするとRailsは2番目のSQLクエリを実行しますuser.applications
(また、ユーザーに関連付けられたすべてのアプリケーションを返すため、id
&key
条件を無視しているように見えます)
user = User.where(email: args[:username]).joins(:applications).merge(
JwtApplication.where(id: args[:application][:id], key: args[:application][:key])
).references(:applications_users).take!
これにより、ユーザーと正しいアプリケーションが正しく取得されます (イェイ!)。しかし、Rails を呼び出そうとすると、2 つ目の SQL クエリが実行されますuser.applications_users
。また、テーブル内のすべてのデータのコレクションが返されます (ここでも&条件applications_users
は無視されます)。id
key
user = User.where(email: args[:username]).joins(:applications).where(
jwt_applications: {
id: args[:application][:id],
key: args[:application][:key]
}
).take!
これで正しいユーザーが取得されますが、アクセスしようとすると Rails は別の SQL クエリを実行し、user.applications
すべてのアプリケーションも返します。
とにかく、うまくいけば、Rails の天才がこの質問に光を当てることができます! 私が Rails の専門家ではないことを最初に認めます。私は過去 10 年間、PHP と C++ でプロとしてのキャリア コーディングを行ってきました。