在 Rails 5 專案中,我有一個用于當前使用 SQL 字串的關聯的查詢方法,我正在嘗試將其重構為僅使用 Arel。我想知道是否可以在不使用to_sqland的情況下撰寫整個查詢方法find_by_sql。
該查詢是一個帶有連接表的 INNER_JOIN。
這是舊的 SQL 字串方法:
class User < AbstractModel
...
# Return an Array of Projects that this User is an admin for.
def projects_admin
@projects_admin ||= Project.find_by_sql(%(
SELECT projects.* FROM projects, user_groups_users
WHERE projects.admin_group_id = user_groups_users.user_group_id
AND user_groups_users.user_id = #{id}
))
end
這是我的 Arel 重寫,它得到相同的查詢結果:
# Return an Array of Projects that this User is an admin for.
def projects_admin
projects = Project.arel_table
# for join tables with no model, need to create an Arel::Table object
# so we can use Arel methods on it, eg access columns
u_g_users = Arel::Table.new("user_groups_users")
arel = projects.project(Arel.star).join(u_g_users).
on(projects[:admin_group_id].eq(u_g_users[:user_group_id]).
and(u_g_users[:user_id].eq(id)))
# is there a way to write this without going to_sql and back?
Project.find_by_sql(arel.to_sql)
end
我想要做的是更改我的新projects_admin方法的最后一行,以便它直接呼叫關系,而不使用find_by_sqlon arel.to_sql。
如果我只回傳,它不是我所期望arel的 s 陣列。Project
但也許這是一種荒謬的愿望,必須這樣表述。許多例子表明情況確實如此。
我已經嘗試了我能找到的每一個例子,但我認為問題的根源是我對連接如何與我正在生成的物件類互動的誤解,一個Arel::SelectManager.
以下是有問題的模型關聯。“user_groups_users”是“user_groups”和“users”之間的連接表——這里只有“User”、“UserGroup”和“Project”模型。
class User < AbstractModel
has_many :projects_created, class_name: "Project"
has_and_belongs_to_many :user_groups,
class_name: "UserGroup",
join_table: "user_groups_users"
class UserGroup < AbstractModel
has_and_belongs_to_many :users
has_one :project
has_one :admin_project, class_name: "Project", foreign_key: "admin_group_id"
class Project < AbstractModel
belongs_to :admin_group, class_name: "UserGroup",
foreign_key: "admin_group_id"
belongs_to :user
belongs_to :user_group
uj5u.com熱心網友回復:
我相信您忽略了一個更簡單的解決方案,即添加間接關聯并執行 LEFT JOIN:
class Project < AbstractModel
belongs_to :admin_group, class_name: "UserGroup",
foreign_key: "admin_group_id"
has_many :admin_group_users,
through: :admin_group,
source: :users # the name of the assocation on UserGroup
# ...
end
Project.joins(:admin_group_users)
.where(users: { id: id })
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/433909.html
