【发布时间】:2019-10-18 21:23:29
【问题描述】:
我有一个账户模型,有很多项目,还有一个项目模型,有很多需求。一个账户作为图书馆账户,其他账户是用户账户。
需求表有一个external_id,它是一个字符串id,用于与外部数据库关联,在账户上下文中是唯一的。但是库帐户和用户帐户中的需求可以共享相同的 external_id(即“REQ-23”),因此它不是 Requirement 表上的唯一键。
有一个 RelatedRequirement 表,用于映射相关的需求。
下面,我想通过在我的 has_many 范围内检查 account_id 来获取属于用户帐户的相关要求。
数据库端:
account
id
project
id
account_id
requirement
id
project_id
external_id
related_requirements
external_id
related_external_id
模型方面:
class RelatedRequirement < ActiveRecord::Base
belongs_to :requirement,,
foreign_key: :external_id,
class_name: "Requirement",
primary_key: :external_id
belongs_to :related_requirement,
foreign_key: :related_external_id,
class_name: "Requirement",
primary_key: :external_id
end
class Requirement < ActiveRecord::Base
belongs_to :project
has_one :account, through: :project
has_many :related_requirement_mappings,
foreign_key: :external_id,
class_name: "RelatedRequirement",
primary_key: :external_id
has_many :related_requirements,
# === this works ===
#-> { joins(:project).where(projects: {account_id: 2 }) },
# === this doesn't work ===
-> { joins(:project).where(projects: {account_id: project.account_id }) },
through: :related_requirement_mappings,
foreign_key: :related_external_id,
class_name: "Requirement",
primary_key: :external_id
我的问题:
- 主要问题,我希望能够使用上面的 has_many :related_requirements 在同一帐户中获取related_requirements,但我无法在我的范围内获取关联的account_id,
>req = Requirement.find(1)
>req.related_requirements
Requirement Load (81.3ms) SELECT "requirements".* FROM "requirements"
NameError (undefined local variable or method `project' for #<Requirement::ActiveRecord_Relation:0x00007fe3f0b1ac20>)
然而,我目前可以做的是:
class Requirement < ActiveRecord::Base
has_many :related_requirements,
#-> { joins(:project).where(prjects: {account_id: project.account_id }) },
through: :related_requirement_mappings,
foreign_key: :related_external_id,
class_name: "Requirement",
primary_key: :external_id
scope :for_account, -> (account) { joins(:project).where(projects: {account_id: account.id}) }
>req = Requirement.find(1)
>req.related_requirements.for_account(req.account)
这看起来有点傻,因为看起来我在 req 上调用了一个实例方法,而且我应该能够从 related_requirements 内部访问 req 的帐户,而不必定义这个额外的 for_account 范围。
- 由于external_id 不是唯一字段,RelatedRequirement 表中的belongs_to 需求实际上可以映射到多个需求,但它只返回一个。理想情况下,我想添加一个范围条件(基于克隆的另一个数据库字段),表明它来自图书馆帐户。但是,如果我这样做,那么上面的related_requirements 查询将会中断,因为范围条件将包含在查询中,并且不再返回用户帐户的related_requirements,我很感兴趣。我不确定我在 RelatedRequirement 范围中指定的条件是如何应用到我为 Requirement 定义的范围中的,而我没有明确调用它。
class RelatedRequirement < ActiveRecord::Base
belongs_to :requirement,
-> { where cloned: nil },
foreign_key: :external_id,
class_name: "Requirement",
primary_key: :external_id
belongs_to :related_requirement,
-> { where cloned: nil },
foreign_key: :related_external_id,
class_name: "Requirement",
primary_key: :external_id
class Requirement < ActiveRecord::Base
belongs_to :project
has_one :account, through: :project
has_many :related_requirement_mappings,
foreign_key: :external_id,
class_name: "RelatedRequirement",
primary_key: :external_id
has_many :related_requirements,
# -> { joins(:project).where(projects: {account_id: project.account_id }) },
through: :related_requirement_mappings,
foreign_key: :related_external_id,
class_name: "Requirement",
primary_key: :external_id
scope :for_account, -> (account) { joins(:project).where(projects: {account_id: account.id}) }
irb(main):060:0> r.related_requirements.to_sql
=> "SELECT \"requirements\".* FROM \"requirements\" INNER JOIN \"related_requirements\" ON \"requirements\".\"external_id\" = \"related_requirements\".\"related_external_id\" WHERE \"related_requirements\".\"external_id\" = 'REQ-1' AND \"requirements\".\"cloned\" IS NULL"
irb(main):061:0> r.related_requirements.for_account(r.account)
=> #<ActiveRecord::AssociationRelation []>
【问题讨论】:
标签: ruby-on-rails activerecord