【问题标题】:What role do ActiveRecord model constructors have in Rails (if any)?ActiveRecord 模型构造函数在 Rails(如果有的话)中有什么作用?
【发布时间】:2009-11-11 17:00:27
【问题描述】:

我刚刚阅读了this question,它是关于为 ActiveRecord 模型的日期字段提供默认值的。接受的答案显示了如何从控制器内设置默认值。在我看来,这种业务逻辑确实属于模型本身。

然后我开始思考,如果这是 Java,我可能会在声明实例变量时或在构造函数中设置初始字段值。由于数据库支持的字段不必在 ActiveRecord 模型中显式声明,这是您可以使用模型的 initialize 方法的东西吗?我很好奇,因为在我看过的 Rails 代码中,我并没有真正看到过多使用 ActiveRecord 模型的构造函数。他们有没有可以发挥的作用?如果有,它是什么?

【问题讨论】:

    标签: ruby-on-rails activerecord constructor


    【解决方案1】:

    实际上,我经常为默认值执行此操作。它运行良好,仍然允许用户更改它。请记住,当您说MyObject.new 时会调用初始化方法。但是,您可能想阅读 this blog entry(虽然有点过时)关于使用 initialize 的信息。

    您应该使用after_initialize 而不是initialize。 ActiveRecord::Base 需要 initialize 方法来准备许多便利方法。如果在您的模型中定义了 after_initialize 方法,它会被调用为对 new、create、find 和任何其他生成模型实例的方法的回调。

    理想情况下,您应该像这样定义它:

    def after_initialize
      @attribute ||= default_value
    end
    

    另外请注意,您不能像其他回调一样使用此回调,您必须定义一个名为 after_initialize 的方法(如上所示)才能使其工作。您不能执行以下操作:

    after_initialize :run_some_other_method
    

    【讨论】:

    • 我使用类似的技术来缓存基于字段的内部属性,而不是一遍又一遍地进行相同的计算。
    • 非常感谢。对于那些寻找解释为什么必须这样定义它的人 - stackoverflow.com/q/3826153/242426
    • 这似乎随着 Rails 4 / ActiveRecord 4.2.0 而改变。详情请见my answer
    【解决方案2】:

    @TopherFangio 的回答是正确的。似乎 ActiveRecord API 在他的回答(2009 年)和现在(2015 年)之间发生了变化。

    从今天开始(带有 ActiveRecord 4.2.0 的 Rails 4),以下是添加初始化程序的方法according to the ActiveRecord docs

    class Widget < ActiveRecord::Base
      after_initialize |new_widget|
        new_widget.name ||= 'Unnamed Widget'
      end
    end
    

    您可以使用puts 语句或检查来自rails console 的新对象来验证它实际上是否正确初始化。

    【讨论】:

      【解决方案3】:

      根据这个blog,活动记录并不总是使用new,因此可能不会在您的对象上调用initialize。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-10-13
        • 1970-01-01
        • 2017-03-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-24
        相关资源
        最近更新 更多