Rails使用默认值初始化新对象

时间:2013-12-05 17:14:11

标签: ruby-on-rails ruby activerecord

我有以下课程:

class Question < ActiveRecord::Base
  attr_accessible :choices
end

我想初始化新对象,在数组中有4个空字符串,所以choices = ['','','','']。我已经尝试在控制器中执行此操作:

def new
  @question = Question.new(:choices => ['','','',''])
end

这样可行,但似乎应该在模型中完成此操作以提升数据完整性。有更好的方法吗?

2 个答案:

答案 0 :(得分:2)

您有多种解决方案。按优先顺序

  1. 创建自定义方法,并在需要此类功能时使用

    class Question < ActiveRecord::Base
      attr_accessible :choices
    
      def self.prepare
        new(:choices => ['','','',''])
      end
    end
    
  2. 使用after_initialize回调

    class Question < ActiveRecord::Base
      attr_accessible :choices
    
      after_initialize :default_choices
    
      protected
    
      def :default_choices
        self.choices ||= ['','','','']
      end
    end
    
  3. 覆盖choices

  4. 我鼓励第一种方法有几个原因

    1. 您可以更好地控制代码。只有在您明确需要时才会分配默认值。事实上,有几种情况下,该记录的实例被初始化(考虑测试),并且大部分时间可能不需要分配
    2. 这是向公开未与ActiveRecord紧密耦合的自定义API迈出的一大步。
    3. 它暴露了一种更易于维护的方法
    4. 如果您的应用复杂性会增加,您会喜欢它

答案 1 :(得分:0)

另一种解决方案:

4 在迁移中设为默认值

class CreateQuestions < ActiveRecord::Migration
 def change
   create_table :questions do |t|
     t.string :choices, default: ['', '', '', '']
     t.timestamps
   end
 end
end

但我同意第一个是最好的解决方案。

在任何情况下都不要覆盖初始化http://blog.dalethatcher.com/2008/03/rails-dont-override-initialize-on.html,请使用第二个解决方案中描述的 after_initialize 回调。