是否可以在连接查询中添加条件?
例如,我想构建下一个查询:
select * from clients
left join comments on comments.client_id = clients.id and comments.type = 1
Client.joins(:comments).all
仅生成:
select * from clients
left join comments on comments.client_id = clients.id
PS。 Client.joins("LEFT JOIN comments on comments.client_id = clients.id and comment.type = 1")
并不好。
答案 0 :(得分:1)
你可以这样做:
Client.left_outer_joins(:comments)
.where(comments: { id: nil })
.or(Client.left_outer_joins(:comments)
.where.not(comments: { id: nil })
.where(comments: { type: 1 }))
什么能给你提供与你想要的东西相同的东西:
SELECT "clients".*
FROM "clients"
LEFT OUTER JOIN "comments"
ON "comments"."client_id" = "clients"."id"
WHERE "comments"."id" IS NULL
OR ("comments"."id" IS NOT NULL) AND "comments"."type" = 1
更新
实际上,这不起作用,因为rails关闭了括号,不在类型的评估之外。
更新2
如果您的评论类型很少且不太可能会改变其值,您可以通过以下方式解决:
class Client < ApplicationRecord
has_many :comments
has_many :new_comments, -> { where comments: { type: 1 } }, class_name: Comment
has_many :spam_comments, -> { where comments: { type: 2 } }, class_name: Comment
end
class Comment < ApplicationRecord
belongs_to :client
end
现在您可以在模型中使用这种新关系:
Client.left_joins(:comments)
给出:
SELECT "clients".*
FROM "clients"
LEFT OUTER JOIN "comments"
ON "comments"."client_id" = "clients"."id"
Client.left_joins(:new_comments)
给出:
SELECT "clients".*
FROM "clients"
LEFT OUTER JOIN "comments"
ON "comments"."client_id" = "clients"."id" AND "comments"."type" = ?
/*[["type", 1]]*/
Client.left_joins(:spam_comments)
给出相同的查询:
SELECT "clients".*
FROM "clients"
LEFT OUTER JOIN "comments"
ON "comments"."client_id" = "clients"."id" AND "comments"."type" = ?
/*[["type", 2]]*/
Client.left_joins(:new_comments).where name: 'Luis'
给出:
SELECT "clients".*
FROM "clients"
LEFT OUTER JOIN "comments"
ON "comments"."client_id" = "clients"."id" AND "comments"."type" = ?
WHERE "clients"."name" = ?
/*[["type", 1], ["name", "Luis"]]*/
注:
我尝试在原始的has_many关系中使用参数,如...
has_many :comments, -> (t) { where comments: { type: t } }
但这给了我一个错误:
ArgumentError:关联范围&#39;评论&#39;是实例相关的(范围块采用参数)。不支持预加载实例相关的范围。
答案 1 :(得分:0)
Client.joins(:comments).where(comments: {type: 1})
试试这个