在rails中默认创建has_one依赖项

时间:2017-03-10 01:24:41

标签: ruby-on-rails activerecord

我想了解在rails中创建模型依赖关系的最佳实践。场景很简单。这两个模型是:

class Main < ActiveRecord::Base 
    has_one :dependent
    validates :dependent, presence: true
end

class Dependent < ActiveRecord::Base 
end

(请注意,我想验证以确保依赖项始终存在)

每当创建Main对象时,我希望创建一个Dependent对象并“默认初始化”。我来自C ++的背景,因此我将此问题视为构造一个类型为class的成员变量的一个,该变量具有默认构造函数。

我有很多方法可以解决这个问题。

  1. before_validation中添加逻辑以创建Dependent
  2. 这感觉非常“不耐烦”。我想在before_create中执行此操作,但验证在回调之前完成。在before_validation中执行此操作非常难看,因为在更新时在create 上都会调用此回调,这会使逻辑变得棘手/混乱。

    1. 将逻辑放入.new
    2. 这感觉非常非常“un-railsy”,可能在概念上是错误的。我会看到new执行ActiveRecord构建,这是在构建模型之前发生的。

      1. 让来电者开展工作
      2. 每当创建Main对象时,必须通过new-save而不是create来完成。然后调用代码必须自己创建Dependent,尽管有默认值,例如

        Main.new do |m|
            m.dependent = Dependent.create
        end
        

        这对调用者来说非常麻烦,导致很多重复的代码。我可以把它打包成一个工厂类型的方法,但同样的问题是调用代码需要做一些工作。

        这是否有规范的解决方案?

2 个答案:

答案 0 :(得分:0)

您应该尝试使用after_create callback并在此方法中创建Dependent实例。

答案 1 :(得分:0)

为了回答我自己的问题,我发现了一个我之前没有看过的回调:#accepts_nested_attributes_for。我可以在这里做我想做的事。

其他人的说明:

我的特殊情况非常简单,因为我总是希望我的依赖类默认初始化,用户不需要设置任何东西。但是,在更复杂的情况下,这不会起作用并初始化家属可能需要:

  1. 创建网站的显式初始化
  2. 用户使用{{1}}
  3. 初始化从属关系的UI