这将为您提供与表中行的属性team_id
匹配的所有收藏夹,用于特定团队(此处为具有 id 的团队):external_id
teams
3333
Favorite.joins("left outer join teams on teams.external_id = favorites.team_id")\
.where('team_id' => 3333)
正如我在评论中提到的那样,这里的棘手之处在于,当您将模型上的外部id Team
(您创建的属性)与模型team_id
上的Favorite
(使用整个rails获取和分配关联)。
一旦您尝试真正获得您在上述加入中找到的最爱的团队,您就会看到问题:
f = Favorite.joins("left outer join teams on teams.external_id = favorites.team_id")\
.where('team_id' => 3333).first
=> #<Favorite id: 1, user_id: nil, team_id: 3333, points: nil, created_at: ... >
f.team
Team Load (0.3ms) SELECT "teams".* FROM "teams" WHERE "teams"."id" = 3333 LIMIT 1
=> nil
这里发生了什么?如果您仔细查看查询,您会发现 rails 正在选择3333 的团队id
。请注意,它不是在寻找外部id 为 3333 的团队,这正是您想要的。
根本问题是您试图使用外部 id(特定于您的 API 的 id)进行关联,这是行不通的。事实上,没有理由这样做。
相反,试试这个:
Favorite.joins(:team).where('teams.external_id = 3333')
这将为您提供所有其团队具有外部 id 3333 的收藏夹。请注意,Rails 将通过加入来做到这一点teams.id = favorites.team_id
,然后过滤teams.external_id
:
SELECT "favorites".* FROM "favorites" INNER JOIN "teams"
ON "teams"."id" = "favorites"."team_id" WHERE (teams.external_id = 3333)
你可以反过来做同样的事情:
Team.joins(:favorites).where('teams.external_id = 3333')
这将生成 SQL:
SELECT "teams".* FROM "teams" INNER JOIN "favorites"
ON "favorites"."team_id" = "teams"."id" WHERE (teams.external_id = 3333)
再次注意,它是id
连接中使用的,而不是外部 id。这是执行此操作的正确方法:id
对您的关联使用常规,然后只需在必要时通过您的(自定义的、特定于 API 的)外部 id 进行过滤。
希望有帮助!
更新:
从评论看来,team_id
您的Favorite
模型上的 似乎是从 API 数据定义的,这意味着 id 对应于external_id
您的Team
模型。这是一个坏主意:在 rails 中,外键<model name>_id
(team_id
,user_id
等)具有特定含义:id 被理解为映射到id
相应关联模型的字段(Team
)。
为了让您的关联起作用,您需要使用 ids(而不是外部 ids)用于任何地方的关联(也与您的User
模型一起使用)。为此,您需要将 API 中定义的关联转换为 rails 应用程序中的 id。当您从 API 添加收藏夹时,找到与id
API 团队 id 对应的团队。
external_team_id = ... # get external team id from API JSON data
favorite.team_id = Team.find_by_external_id(external_team_id).id
因此,您正在id
为团队分配给定的外部 ID。您需要为从 API 加载的每个收藏夹查询数据库,这在性能方面可能会付出高昂的代价,但因为您只在没什么大不了的时候才这样做。