gpt4 book ai didi

ruby-on-rails - User 模型中的父子关系(自联接)

转载 作者:行者123 更新时间:2023-12-04 07:35:32 25 4
gpt4 key购买 nike

在 Rails 中,我有这个 User 模型:

class User < ActiveRecord::Base
enum role: [:adult, :child, :admin]
after_initialize :set_default_role, :if => :new_record?

# belongs_to :spouse, :foreign_key => :spouse_id, :class_name => 'User', :inverse_of => :spouse

def set_default_role
self.role ||= :adult
end

# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable, :confirmable,
:recoverable, :rememberable, :trackable, :validatable


def marry(user)
self.spouse = user
user.spouse = self
end
end

我通过这次迁移添加了配偶:
class AddFieldsToUser < ActiveRecord::Migration
def change
# for marriages
add_column :users, :spouse_id, :integer, index: true
end
end

并且效果很好(尽管我的逆函数从未起作用 # belongs_to :spouse, :foreign_key => :spouse_id, :class_name => 'User', :inverse_of => :spouse
)。我现在正在尝试通过“ child - parent ”关系进行另一个自我加入。一个 parent 可以有很多 child ,一个 child 可以有(很多/两个) parent 。这是我想出的迁移:
class CreateParentalRelationships < ActiveRecord::Migration
def change
create_table :parental_relationships do |t|
t.references :parent, index: true
t.references :child
end
end
end

我将它添加到模型中:
  has_many :children, :through => :parental_relationships, class_name: "User"
has_many :parents, :through => :parental_relationships, class_name: "User"

但该关系因以下错误而无效:
[7] pry(main)> u = User.find(3)
User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 3]]
=> #<User id: 3, email: ...>

[8] pry(main)> u.children
ActiveRecord::HasManyThroughAssociationNotFoundError: Could not find the association :parental_relationships in model Us
er

[9] pry(main)> u.parent
NoMethodError: undefined method `parent' for #<User:0x5e52eb0>
from C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activemodel-4.1.8/lib/active_model/attribute_methods.rb:435:in
`method_missing'

[10] pry(main)> u.parents
ActiveRecord::HasManyThroughAssociationNotFoundError: Could not find the association :parental_relationships in model Us
er
from C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activerecord-4.1.8/lib/active_record/reflection.rb:690:in `che
ck_validity!'

[11] pry(main)> u2.children
ActiveRecord::HasManyThroughAssociationNotFoundError: Could not find the association :parental_relationships in model Us
er
from C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activerecord-4.1.8/lib/active_record/reflection.rb:690:in `che
ck_validity!'

我错过了什么?

最佳答案

建立父子关系需要一些麻烦。

class ParentalRelationship < ActiveRecord::Base
belongs_to :parent, class_name: 'User'
belongs_to :child, class_name: 'User'
end
class User < ActiveRecord::Base
has_many :parent_relationships,
foreign_key: 'child_id',
class_name: 'ParentalRelationship'

has_many :child_relationships,
foreign_key: 'parent_id',
class_name: 'ParentalRelationship'

has_many :parents,
through: :parent_relationships,
class_name: 'User'

has_many :children,
through: :child_relationships,
class_name: 'User'

has_and_belongs_to_many :marriages
belongs_to :current_marriage, class_name: 'Marriage'

def marry(spouse)
marriage = Marriage.create(users: [self, spouse])
marriage.users.each { |u| u.update(current_marriage: marriage ) }
marriage
end

def spouse
return nil unless current_marriage
current_marriage
.users.where.not('marriages_users.user_id' => id).first
end

def birth(child)
child.parents << self
child.parents << spouse if spouse
end
end

请注意,我们需要设置与 ParentalRelationship 的关系。两次,因为我们需要告诉 rails 它应该为每种类型的关系(用户是父级还是子级)查看哪个外键。

由于在现代,人们实际上可以结过几次婚,因此我们需要一个婚姻模型和一个用于 users_marriages 的连接表。
class Marriage < ActiveRecord::Base
has_and_belongs_to_many :users
validates :users, length: { minimum: 2, maximum: 2 }
end
rails g migration CreateUsersMarriagesJoinTable users marriages

具有规范的示例应用程序: https://github.com/maxcal/sandbox/tree/31614819

关于ruby-on-rails - User 模型中的父子关系(自联接),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31614819/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com