通过三个关联查询where方法
Query for where method through three associations
我有三个模型:
Invitation.rb
belongs_to :department
Department.rb
belongs_to :organisation
has_many :invitations
Organisation.rb
has_many :departments
组织 table 有 tag
字段。
我需要编写一个查询来搜索邀请,其组织有一个 tag
字段,内容为 'First tag'
像这样:
Invitation.joins(:department).joins(:organisation).where(tag: 'First tag')
但我不知道如何构建这样的查询。
Invitation.joins(department: :organisation).where(organisations: { tag: 'First tag' })
为什么?因为对于 "reach" 组织 table 的邀请,您可以使用部门之间的关系 table。
Table.joins(...).joins(...)
是"joining"两倍table,你需要的是参考部门和组织之间的关系。你可以这样做:
{ department: :organisation }
将其传递给 join 会在接收器中使用 departments
加载 JOIN 子句,并在 departments
中使用 organisations
.
注意 where 子句可以用作 { organisations: { tag: ... } }
或 ["organisations.tag = ?", ...]
,它们可以互换使用。您使用什么只是您或您同事的偏好问题。
要在不更改模型的情况下完成您正在尝试做的事情,您应该将散列传递给连接方法,如下所示:
Invitation.joins(department: :organisation).where(organisations: { tag: 'First tag' })
这告诉 ActiveRecord 使用邀请模型中定义的部门关联和部门模型中的组织关联
为了让您的生活更轻松一些,您可以像这样添加 has_many through
关联:
class Invitation < ApplicationRecord
belongs_to :department
has_one :organisation, through: :department
end
class Department < ApplicationRecord
belongs_to :organisation
has_many :invitations, inverse_of: :department
end
class Organisation
has_many :departments, inverse_of: :organisation
has_many :invitations, through: :departments
end
现在您可以在组织上使用邀请关系,如下所示:
Invitation.joins(:organisation).where(tag: 'First tag')
要查看 sql(例如在控制台中),您可以使用 #to_sql 方法:
Invitation.joins(:organisation).where(tag: 'First tag').to_sql
最后,如果您使用范围(并且不喜欢必须在其中指定 table 的 where 方法中的散列),您可以使用 "scope" 并按如下方式合并:
class Organisation
class << self
def just_tagged
where(tag: 'First tag')
end
end
end
现在您可以使用 merge
:
在查询中引用范围
Invitation.joins(:organistion).merge(Organisation.just_tagged)
我有三个模型:
Invitation.rb
belongs_to :department
Department.rb
belongs_to :organisation
has_many :invitations
Organisation.rb
has_many :departments
组织 table 有 tag
字段。
我需要编写一个查询来搜索邀请,其组织有一个 tag
字段,内容为 'First tag'
像这样:
Invitation.joins(:department).joins(:organisation).where(tag: 'First tag')
但我不知道如何构建这样的查询。
Invitation.joins(department: :organisation).where(organisations: { tag: 'First tag' })
为什么?因为对于 "reach" 组织 table 的邀请,您可以使用部门之间的关系 table。
Table.joins(...).joins(...)
是"joining"两倍table,你需要的是参考部门和组织之间的关系。你可以这样做:
{ department: :organisation }
将其传递给 join 会在接收器中使用 departments
加载 JOIN 子句,并在 departments
中使用 organisations
.
注意 where 子句可以用作 { organisations: { tag: ... } }
或 ["organisations.tag = ?", ...]
,它们可以互换使用。您使用什么只是您或您同事的偏好问题。
要在不更改模型的情况下完成您正在尝试做的事情,您应该将散列传递给连接方法,如下所示:
Invitation.joins(department: :organisation).where(organisations: { tag: 'First tag' })
这告诉 ActiveRecord 使用邀请模型中定义的部门关联和部门模型中的组织关联
为了让您的生活更轻松一些,您可以像这样添加 has_many through
关联:
class Invitation < ApplicationRecord
belongs_to :department
has_one :organisation, through: :department
end
class Department < ApplicationRecord
belongs_to :organisation
has_many :invitations, inverse_of: :department
end
class Organisation
has_many :departments, inverse_of: :organisation
has_many :invitations, through: :departments
end
现在您可以在组织上使用邀请关系,如下所示:
Invitation.joins(:organisation).where(tag: 'First tag')
要查看 sql(例如在控制台中),您可以使用 #to_sql 方法:
Invitation.joins(:organisation).where(tag: 'First tag').to_sql
最后,如果您使用范围(并且不喜欢必须在其中指定 table 的 where 方法中的散列),您可以使用 "scope" 并按如下方式合并:
class Organisation
class << self
def just_tagged
where(tag: 'First tag')
end
end
end
现在您可以使用 merge
:
Invitation.joins(:organistion).merge(Organisation.just_tagged)