Ruby on rails 双重自指模型
考虑到基于遗传学的建模,单个模型旨在与postgresql具有两组自参考关系 “家长路线”相当直截了当Ruby on rails 双重自指模型,ruby-on-rails,postgresql,Ruby On Rails,Postgresql,考虑到基于遗传学的建模,单个模型旨在与postgresql具有两组自参考关系 “家长路线”相当直截了当 class Parent < ApplicationRecord belongs_to :parent_gestator, class_name: 'Individual' belongs_to :parent_nongestator, class_name: 'Individual' end class Individual < ApplicationRecord
class Parent < ApplicationRecord
belongs_to :parent_gestator, class_name: 'Individual'
belongs_to :parent_nongestator, class_name: 'Individual'
end
class Individual < ApplicationRecord
has_many :parent_gestators, foreign_key: :parent_gestator_id, class_name: 'Parent'
has_many :parent_nongestators, foreign_key: :parent_nongestator_id, class_name: 'Parent'
has_many :children, through: :parent_gestators
has_many :children, through: :parent_nongestators
end
类父级
注:has_many关系允许多个父母通过血缘关系或领养关系
问题是“如何建立第二个自我参照,即配偶关系的自我参照”?。i、 e.两个个体的结合,没有父母(因此也没有兄弟姐妹)关系。
经过几次推理得出了一个非常简洁的定义
class Individual < ApplicationRecord
has_many :spouses, foreign_key: :spouse_id, class_name: 'Individual'
end
class-Individual
然而,有一种烦人的感觉,这是不正确的/不完整的。上述是否正确/充分?对我来说,拥有一个显式父类似乎有点不吉利,因为它需要一个存在成为两个模型的记录,例如,当它有父类和子类时。我会将模型重构成这样:
class Individual < ActiveRecord::Base
class Relationship < ActiveRecord::Base
self.table_name = 'relationships'
class ParentChild < Relationship
belongs_to :parent,
class_name: 'Individual',
foreign_key: :individual_1_id
belongs_to :child,
class_name: 'Individual',
foreign_key: :individual_2_id
end
class Marriage < Relationship
belongs_to :spouse_1,
class_name: 'Individual',
foreign_key: :individual_1_id
belongs_to :spouse_2,
class_name: 'Individual',
foreign_key: :individual_2_id
end
end
def children
children_relationships.map{ |rel| rel.child }
end
def children_relationships
Relationship::ParentChild.where(parent: self)
end
def spouses
spouse_relationships.map do |rel|
rel.spouse_1 == self ? rel.spouse_2 : rel.spouse_1
end
end
def spouse_relationships
clause = "individual_1_id = #{self.id} OR individual_2_id = #{self.id}")
Relationship::Marriage.where clause
end
def parent_relationships
Relationship::ParentChild.where(child: self)
end
def parents
parent_relationships.map{ |rel| rel.parent }
end
end
然后,用法很简单:
father = Individual.create(name: 'John')
=> #<Individual id: 7, name: "John">
mother = Individual.create(name: 'Jane')
=> #<Individual id: 8, name: "Jane">
Individual::Relationship::Marriage.create(spouse_1: father, spouse_2: mother)
=> #<Individual::Relationship::Marriage individual_1_id: 7, ...>
father.spouses
=> [#<Individual id: 8, name: "Jane">]
child_1 = Individual.create(name: 'Tom')
#<Individual id: 9, name: "Tom">
Individual::Relationship::ParentChild.create(parent: father, child: child_1)
Individual::Relationship::ParentChild.create(parent: mother, child: child_1)
child_1.parents
=> [#<Individual id: 7, name: "John">, #<Individual id: 8, name: "Jane">]
father=Individual.create(名字:'John')
=> #
母亲=个人。创建(名称:“Jane”)
=> #
个人::关系::婚姻。创建(配偶1:父亲,配偶2:母亲)
=> #
父亲、配偶
=> [#]
child_1=个人。创建(名称:“Tom”)
#
个人::关系::ParentChild.create(父:父,子:子1)
个人::关系::ParentChild.create(父:母,子:子1)
儿童家长
=> [#, #]
当然,如果愿意,可以解调这些类。我喜欢嵌套类,因为它们向Relationship
传递意义,并且您可以在其他实体之间建立其他类型的关系,而不会在顶级名称空间中产生概念冲突
另一种方法是用婚姻和配偶之间的全面的1:n关系,即个人关系,来取代这些丑陋的个人身份证。这将为三方联姻和Rails复杂的接受机制的嵌套属性打开大门。我没有时间完成这项工作,但如果可以,请发布你的结果
我想从这里,你可以进一步充实它!如果有任何问题,请告诉我。此答案不直接回答上述问题
在处理这一问题时,一对或多个认识走到了最前沿。
a) 对于嵌套类有一个很好的观点。当处理不是数据表对象的推断类时,尤其是当它们的含义几乎完全与主模型关联时,嵌套更有意义(我发现这一点,因为在文档分离的情况下,这两个类之间存在看不见的间隙)
b) 基本逻辑有些复杂,但主要不反映现实。鉴于这是遗传学,有亲生父母(可能还有其他人),到此为止。因此,一个拥有自己表的主类将引用个人
belongs_to :biological_mother, foreign_key: :biological_mother_id, class_name: 'Individual'
belongs_to :biological_father, foreign_key: :biological_father_id, class_name: 'Individual'
(然后,生物结合可以在实践中通过父母和个人来增强)
然后是有亲生父母的个体班级
belongs_to :union
has_many :children_of_father, foreign_key: :biological_father_id, class_name: 'Union'
has_many :children_of_mother, foreign_key: :biological_mother_id, class_name: 'Union'
对联合体和子体的多个引用简洁地定义为
def biological_unions
Union.where('biological_father_id = ? OR biological_mother_id = ?', self.id, self.id).all
end
def children
union_ids = Union.where('biological_father_id = ? OR biological_mother_id = ?', self.id, self.id).pluck(:id)
children = Individual.where('union_id IN (?)', union_ids)
end
5个建模语句,2个方法。[许多fodd供思考解包]我不确定嵌套类与两个类相比有什么好处;db表仍然是唯一的。这可能是一个偏好的问题。我的问题是属于
子类,因为它不允许多对多关系(想想收养、不确定的父母……)。整个过程让我对最初的设想产生了疑问。最好有一个工会类来处理一系列边缘案件(一夫多妻制、一夜情、秘密生活……),这对个人类来说并不方便。至于个人是婚姻的配偶1或配偶2的问题,我的观点是,一个联合类的目的是专门应用于一个血系(2个具有m/f属性的个体),任何其他对该联合有“贡献”的个体都将是联合类的一个子类。@Jerome你说得对,这是一个品味问题,如何构建你的模型及其关系。当我试图提出解决方案时,我只是按照自己的喜好。剩下的建议是用成熟的类来模拟个体之间的关系,而不是像has\u many那样的Rails魔术方法。你考虑组建一个工会
班对我来说很合理。也就是说,我目前看不到我能进一步提供什么帮助。随时更新OP或添加更多评论。如果你通知我,我会回来看看我能做什么。
def biological_unions
Union.where('biological_father_id = ? OR biological_mother_id = ?', self.id, self.id).all
end
def children
union_ids = Union.where('biological_father_id = ? OR biological_mother_id = ?', self.id, self.id).pluck(:id)
children = Individual.where('union_id IN (?)', union_ids)
end