1

(请参见下面的示例架构图像)

我正在尝试users使用该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 会执行第二个 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 会执行第二个 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++ 编码,所以如果这是一个愚蠢的问题,请多多包涵 :)

4

1 回答 1

1

不确定这是否是您正在寻找的东西,但是...您可以编写 ActiveRecord 查询,例如(连接模型应该隐式添加到您的查询中):

User.joins(:applications).where(email: email).where(applications: { key: key, id: id})

其中 email、key 和 id 作为参数传递给查询。

在该查询之上,您可以使用选择字段来获取所需的一切:

user = User.joins(:applications).where(email: email).where(applications: { key: key, id: id}).select('users.*, applications.id as appid applications.key as appkey').first

如果没有符合您的条件,这将返回用户模型(如果存在)或空关系。然后,您可以调用这些字段,例如

user.appid

user.appkey

您始终可以调用 select('users.*, application_users.scopes, applications.*)它将返回单个实例中的所有字段(仍在用户模型下)但是像 id 这样的重复字段只会显示一次,这就是为什么最好只获取您想要的字段并给他们像我这样的唯一标识符已经显示了 appid 和 appkey。

同样,可能不是您所追求的,但希望它为您指明正确的方向!

于 2017-06-23T14:34:51.560 回答