无法让 has_many & belongs_to 在同一模型中工作
Can't get has_many & belongs_to in same model to work
好久没在这里问问题了。
由于我刚开始玩 Ruby,无法解决这个问题,所以我决定回到这里寻求指导。
我现在已经看了很多例子,但是我没有找到解决这个问题的正确路径。
想法如下:
你有:
- 一家人
- 一个人
他们的关系如下:
- 家里有一个人'head'
- 每个人都是家庭的一份子(无论是多人还是只有他自己)
现在的验证可能无法执行此操作,但想法是没有头的家庭,没有家庭的人。
我试图用以下方式表达它:
Family class
class Family < ActiveRecord::Base
validates :head_id, presence: true
belongs_to :head, :class_name => Person, foreign_key: 'head_id'
has_many :persons
end
Person class
class Person < ActiveRecord::Base
validates :family_id, presence: true
validates :first_name, presence: true
belongs_to :family
end
有好心人能给我一些建议吗?
迁移在 Person-class 端有一个 family_id,该系列包含一个额外的列 person_id。
Family migration
class CreateFamilies < ActiveRecord::Migration
def change
create_table :families do |t|
t.integer :head_id
t.timestamps null: false
end
end
end
Person migration
class CreatePersons < ActiveRecord::Migration
def change
create_table :persons do |t|
t.string :first_name
t.string :last_name
t.integer :age
t.integer :family_id
t.timestamps null: false
end
end
end
我不确定我是否正确理解了您的代码,但请告诉我什么是发布者 class?我认为你应该这样做:
家庭模型:
has_many:人数
has_one :head, :class_name => 人物, foreign_key: 'head_id'
验证:head_id,存在:真
人物模型:
belongs_to:家庭
验证:family_id,存在:真
验证:first_name,存在:真
一家多人人,有一个人头。这个人属于一家人,是不是一家之主对这个人来说并不重要。
迁移和验证等其他内容仍然相同。
更好地验证 :head 的存在而不是 head_id
class Family < ActiveRecord::Base
validates :head, presence: true
belongs_to :head, :class_name => Person, foreign_key: 'head_id'
has_many :persons
end
人与家庭有两种关系,一种是家长,另一种是家庭成员,您必须验证(正如我在示例中所说的那样)如何处理这种关系。
class Person < ActiveRecord::Base
validates :family, presence: true
validates :first_name, presence: true
belongs_to :family
belongs_to :head, :class_name => 'Family', :foreign_key => 'head_id'
validate :family_id_is_equal_to_head_id
def family_id_is_equal_to_head_id
self.family = self.head
end
end
最终迁移错误,必须定义关系
class CreateFamilies < ActiveRecord::Migration
def change
create_table :families do |t|
t.integer :head_id
t.timestamps null: false
end
end
end
class CreatePersons < ActiveRecord::Migration
def change
create_table :persons do |t|
t.string :first_name
t.string :last_name
t.integer :age
t.belongs_to :family
t.integer :head_family_id
t.timestamps null: false
end
end
end
你在这里有一个循环依赖。你不能创造家庭或人。
循环依赖通常表示缺少第三个元素。
More eloquently and not completely related.
有两种成员资格,头和非头。一旦你在你的代码中让它们变得明显,循环依赖就会被解决。
有几种解决方案,但您需要找到最适合您的解决方案。这是我的。
创建会员加入table
class Family
validates :memberships, presence: true, on: :update
has_many :memberships
has_many :people, through: :membership
after_create :create_head_membership
private
def create_head_membership
memberships.create role: 'head' # to be filled later
end
end
class Membership
belongs_to :family
belongs_to :person
end
class Person
has_many :memberships
has_one :family, through: :membership # has_many, amrite?
validates :memberships, presence: true, on: :update
end
最重要的是避免Person/Family直接操纵,而是创建一些东西来处理这个过程并将其包装在事务中
class God
def make_family head_attrs
fam, head = nil
Family.transaction do
fam = Family.create!
head = Person.create! head_attrs
fam.memberships.first.update_attribute! :person_id, head.id
end
fam
end
end
好久没在这里问问题了。 由于我刚开始玩 Ruby,无法解决这个问题,所以我决定回到这里寻求指导。
我现在已经看了很多例子,但是我没有找到解决这个问题的正确路径。
想法如下:
你有:
- 一家人
- 一个人
他们的关系如下:
- 家里有一个人'head'
- 每个人都是家庭的一份子(无论是多人还是只有他自己)
现在的验证可能无法执行此操作,但想法是没有头的家庭,没有家庭的人。 我试图用以下方式表达它:
Family class
class Family < ActiveRecord::Base
validates :head_id, presence: true
belongs_to :head, :class_name => Person, foreign_key: 'head_id'
has_many :persons
end
Person class
class Person < ActiveRecord::Base
validates :family_id, presence: true
validates :first_name, presence: true
belongs_to :family
end
有好心人能给我一些建议吗?
迁移在 Person-class 端有一个 family_id,该系列包含一个额外的列 person_id。
Family migration
class CreateFamilies < ActiveRecord::Migration
def change
create_table :families do |t|
t.integer :head_id
t.timestamps null: false
end
end
end
Person migration
class CreatePersons < ActiveRecord::Migration
def change
create_table :persons do |t|
t.string :first_name
t.string :last_name
t.integer :age
t.integer :family_id
t.timestamps null: false
end
end
end
我不确定我是否正确理解了您的代码,但请告诉我什么是发布者 class?我认为你应该这样做:
家庭模型:
has_many:人数
has_one :head, :class_name => 人物, foreign_key: 'head_id'
验证:head_id,存在:真
人物模型:
belongs_to:家庭
验证:family_id,存在:真
验证:first_name,存在:真
一家多人人,有一个人头。这个人属于一家人,是不是一家之主对这个人来说并不重要。
迁移和验证等其他内容仍然相同。
更好地验证 :head 的存在而不是 head_id
class Family < ActiveRecord::Base
validates :head, presence: true
belongs_to :head, :class_name => Person, foreign_key: 'head_id'
has_many :persons
end
人与家庭有两种关系,一种是家长,另一种是家庭成员,您必须验证(正如我在示例中所说的那样)如何处理这种关系。
class Person < ActiveRecord::Base
validates :family, presence: true
validates :first_name, presence: true
belongs_to :family
belongs_to :head, :class_name => 'Family', :foreign_key => 'head_id'
validate :family_id_is_equal_to_head_id
def family_id_is_equal_to_head_id
self.family = self.head
end
end
最终迁移错误,必须定义关系
class CreateFamilies < ActiveRecord::Migration
def change
create_table :families do |t|
t.integer :head_id
t.timestamps null: false
end
end
end
class CreatePersons < ActiveRecord::Migration
def change
create_table :persons do |t|
t.string :first_name
t.string :last_name
t.integer :age
t.belongs_to :family
t.integer :head_family_id
t.timestamps null: false
end
end
end
你在这里有一个循环依赖。你不能创造家庭或人。 循环依赖通常表示缺少第三个元素。 More eloquently and not completely related.
有两种成员资格,头和非头。一旦你在你的代码中让它们变得明显,循环依赖就会被解决。
有几种解决方案,但您需要找到最适合您的解决方案。这是我的。
创建会员加入table
class Family
validates :memberships, presence: true, on: :update
has_many :memberships
has_many :people, through: :membership
after_create :create_head_membership
private
def create_head_membership
memberships.create role: 'head' # to be filled later
end
end
class Membership
belongs_to :family
belongs_to :person
end
class Person
has_many :memberships
has_one :family, through: :membership # has_many, amrite?
validates :memberships, presence: true, on: :update
end
最重要的是避免Person/Family直接操纵,而是创建一些东西来处理这个过程并将其包装在事务中
class God
def make_family head_attrs
fam, head = nil
Family.transaction do
fam = Family.create!
head = Person.create! head_attrs
fam.memberships.first.update_attribute! :person_id, head.id
end
fam
end
end