0

Aprojectlegacy_usersgroup_usersgroup_users必须通过groups才能获得users。我想构建一个project.users将这些查询组合为一个arel。

这里是Project

class Project < ActiveRecord::Base
  has_many    :project_accesses

  has_many    :groups,       through: :project_accesses, source: :group
  has_many    :legacy_users, through: :project_accesses, source: :user
  has_many    :group_users,  through: :groups, source: :users
end

这是sql Project.find(1).legacy_users

SELECT "users".* FROM "users" INNER JOIN "project_accesses" ON "users"."id" =
"project_accesses"."user_id" WHERE "users"."deleted_at" IS NULL AND 
"project_accesses"."deleted_at" IS NULL AND "project_accesses"."project_id" = 1

这是sql Project.find(1).group_users

SELECT "users".* FROM "users" INNER JOIN "group_memberships" ON "users"."id" =
"group_memberships"."user_id" INNER JOIN "groups" ON "group_memberships"."group_id" = 
"groups"."id" INNER JOIN "project_accesses" ON "groups"."id" = 
"project_accesses"."group_id" WHERE "users"."deleted_at" IS NULL AND 
"group_memberships"."deleted_at" IS NULL AND "groups"."deleted_at" IS NULL AND 
"project_accesses"."deleted_at" IS NULL AND "project_accesses"."project_id" = 1

通过简单地添加一个OR条件INNER JOIN "project_accesses",我得到了我想要的。Project.find(1).users

SELECT "users".* FROM "users" INNER JOIN "group_memberships" ON "users"."id" = 
"group_memberships"."user_id" INNER JOIN "groups" ON "group_memberships"."group_id" = 
"groups"."id" INNER JOIN "project_accesses" ON ("groups"."id" = 
"project_accesses"."group_id" OR "users"."id" = "project_accesses"."user_id") WHERE 
"users"."deleted_at" IS NULL AND "group_memberships"."deleted_at" IS NULL AND 
"groups"."deleted_at" IS NULL AND "project_accesses"."deleted_at" IS NULL AND 
"project_accesses"."project_id" = 1

基本上我只是改变了让查询做我想做的事:

INNER JOIN "project_accesses" ON ("groups"."id" = "project_accesses"."group_id" OR "users"."id" = "project_accesses"."user_id")

问题是现在,这只是一个传入的字符串find_by_sql,我不知道如何使它成为一个合适的 Arel。

提前感谢您的帮助!

4

2 回答 2

0

您应该能够使用joinsARel 的方法来手动构建您的连接,并且仍然可以获得实时关系。

http://api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html#method-i-joins

于 2013-09-27T03:32:17.043 回答
0

我越来越近了:

User.joins(:groups).joins("inner join project_accesses on (groups.id = 
project_accesses.group_id or users.id = project_accesses.user_id)").
where(project_accesses: {project_id:1}).merge(Group.scoped).
merge(GroupMembership.scoped).merge(ProjectAccess.scoped).uniq

有没有办法在 Arel 中编写这部分?

joins("inner join project_accesses on (groups.id = 
project_accesses.group_id or users.id = project_accesses.user_id)")

此外,有没有办法自动包含所有连接模型的默认范围,以避免:

.merge(Group.scoped).merge(GroupMembership.scoped).merge(ProjectAccess.scoped)
于 2013-09-27T18:39:34.957 回答