У меня есть модель учетной записи, которая имеет много проектов, и модель проекта, которая имеет много требований. Одна учетная запись действует как учетная запись библиотеки, а другие учетные записи являются учетными записями пользователей.
Таблица требований имеетexternal_id, который является строковым идентификатором, который используется для корреляции с внешней базой данных и является уникальным в контексте учетной записи. Но требования в учетной записи библиотеки и учетной записи пользователя могут использовать один и тот же external_id (т. Е. «REQ-23»), поэтому он не является уникальным ключом в таблице требований.
Существует таблица RelatedRequirement,сопоставляет связанные требования.
Ниже я хочу получить связанные требования, относящиеся к учетной записи пользователя, выполнив проверку account_id в моей области действия has_many.
Сторона базы данных:
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
Мои вопросы:
- Mainвопрос, я хотел бы иметь возможность получить related_requirements в той же учетной записи, используя has_many: 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, и я должен иметь возможность доступа к учетной записи req изнутри. related_requirements,без определения этой дополнительной области действия for_account.
Поскольку external_id не является уникальным полем, требование own_to в таблице RelatedRequirement фактически может соответствовать нескольким требованиям, но оно просто возвращает одно. В идеале я хотел бы добавить условие области (основанное на клонированном другом поле базы данных), которое указывает, что это из учетной записи библиотеки. Однако, если я сделаю это, то вышеупомянутый запрос related_requirements будет прерван, поскольку условие области будет включено в запрос и больше не будет возвращать related_requirements учетной записи пользователя, меня это интересует. Я не уверен относительно того, почему условие, которое я указываю в области RelatedRequirement, каким-то образом применяется в областях, которые я определяю для требования, когда я не вызываю его явно.
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 []>