Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails Rails-最佳实践:如何创建依赖关系_Ruby On Rails_Ruby_Activerecord_Ruby On Rails 3_Associations - Fatal编程技术网

Ruby on rails Rails-最佳实践:如何创建依赖关系

Ruby on rails Rails-最佳实践:如何创建依赖关系,ruby-on-rails,ruby,activerecord,ruby-on-rails-3,associations,Ruby On Rails,Ruby,Activerecord,Ruby On Rails 3,Associations,创建has_one关系的最佳实践是什么 例如,如果我有一个用户模型,它必须有一个配置文件 我怎样才能做到呢 一种解决办法是: # user.rb class User << ActiveRecord::Base after_create :set_default_association def set_default_association self.create_profile end end #user.rb class User您的解决方案绝对是一个不错

创建has_one关系的最佳实践是什么

例如,如果我有一个用户模型,它必须有一个配置文件

我怎样才能做到呢

一种解决办法是:

# user.rb
class User << ActiveRecord::Base
  after_create :set_default_association

  def set_default_association
    self.create_profile
  end
end
#user.rb

class User您的解决方案绝对是一个不错的解决方案(至少在您长大后),但您可以简化它:

# user.rb
class User < ActiveRecord::Base
  has_one      :profile
  after_create :create_profile
end
#user.rb
类用户
创建has\u关系的最佳实践是在创建前使用ActiveRecord回调
,而不是在创建后使用
。或者使用更早的回调来处理未通过自身验证步骤的子级的问题(如果有)

因为:

  • 通过良好的编码,如果验证失败,您就有机会向用户显示子记录的验证
  • ActiveRecord更干净,并且明确支持它——AR在保存父记录(在创建时)后自动填充子记录中的外键。AR然后将子记录保存为创建父记录的一部分
如何做:

# in your User model...
has_one :profile
before_create :build_default_profile

private
def build_default_profile
  # build default profile instance. Will use default params.
  # The foreign key to the owning User model is set automatically
  build_profile
  true # Always return true in callbacks as the normal 'continue' state
       # Assumes that the default_profile can **always** be created.
       # or
       # Check the validation of the profile. If it is not valid, then
       # return false from the callback. Best to use a before_validation 
       # if doing this. View code should check the errors of the child.
       # Or add the child's errors to the User model's error array of the :base
       # error item
end

可能不是最干净的解决方案,但我们已经有了一个拥有50万条记录的数据库,其中一些已经创建了“Profile”模型,而一些没有。我们采用了这种方法,它保证在任何时候都存在一个概要文件模型,而不需要遍历并追溯生成所有概要文件模型

alias_method :db_profile, :profile
def profile
  self.profile = Profile.create(:user => self) if self.db_profile.nil?
  self.db_profile
end

我是这样做的。不确定这有多标准,但它工作得很好,而且很懒,因为它不会产生额外的开销,除非有必要建立新的关联(我很高兴在这方面得到纠正):


这也意味着只要你需要,协会就会在那里。我想另一种选择是在初始化后挂接,但这似乎增加了相当多的开销,因为它在每次初始化对象时都会运行,并且有时您可能不想访问关联。检查它的存在似乎是一种浪费。

有一个宝石:


看起来现在有点旧了。(不适用于rails3)

如果这是现有大型数据库中的新关联,我将按照以下方式管理转换:

class User < ActiveRecord::Base
  has_one :profile
  before_create :build_associations

  def profile
    super || build_profile(avatar: "anon.jpg")
  end

private
  def build_associations
    profile || true
  end
end
class用户

这样,现有的用户记录在被要求时会获得一个配置文件,并使用它创建新的用户记录。这也会将默认属性放在一个位置,并与Rails 4以后的accepts_nested_attributes_一起正确工作。

我对此有问题,accepts_nested_attributes_为,因为如果传入嵌套属性,则会在那里创建关联的模型。我最后做了一件事

after_create :ensure_profile_exists
has_one :profile
accepts_nested_attributes_for :profile


def ensure_profile_exists
  profile || create_profile
end

也可以用一条线来管理吗?->在\u筛选器之前:生成\u配置文件?@Lichtamberg:是的,但我要添加一条注释:“生成默认配置文件。必须始终验证。”注意:应该是“在\u创建之前:生成\u配置文件”而不是“在\u筛选器之前”。如果它没有验证,那么用户会收到一个非常令人困惑的错误消息。或者它实际上不会被创建,这意味着你最终会遇到一个没有个人资料的用户。您还应该在测试中测试角落案例。我尝试了此代码,但失败了,我必须执行profile=build\u profile然后如何将此对象添加到新的
用户
,由于这是创建之前的
?请注意,Rails 5在创建之前使用创建从属记录,如果不覆盖所属记录的默认值,则无法创建从属记录。默认情况下,现在期望记录存在,否则会抛出错误。我认为这个答案比其他答案更好,因为可以避免配置文件模型中的验证问题。谢谢你也可以有自动保存:
有一个:profile,:autosave=>true
@montrealmike,这会处理一个缺少的配置文件吗?也就是说,如果尚未执行build_profile,是否会在保存时创建一个?我也遇到过这样的情况:这可能提供了另一种解决多模型表单的方法。@BrendonMuir不,它不会构建缺少的配置文件。这是一个很好的解决方案,但我们正在使用super | | | create|u profile(avatar:“anon.jpg”)来确保新的配置文件立即被保存。@sandre89您有可能遭遇回调噩梦,在before_create回调中使用持久化方法,验证异常和不正确的持久化记录,等等。Avdi Grimm写了一个关于RubyTapas的四集系列,涵盖了许多灾难,这些灾难等待着你让模型层做任何形式的自我拯救。我向你致以最美好的祝愿,但我害怕最坏的结果。
after_create :ensure_profile_exists
has_one :profile
accepts_nested_attributes_for :profile


def ensure_profile_exists
  profile || create_profile
end