我如何在ActiveRecord设置默认值?

我看到Pratik的一篇文章,描述了一段丑陋而复杂的代码:http://m.onkey.org/2007/7/24/how-to-set-default-values-in-your-model

class Item < ActiveRecord::Base  
  def initialize_with_defaults(attrs = nil, &block)
    initialize_without_defaults(attrs) do
      setter = lambda { |key, value| self.send("#{key.to_s}=", value) unless
        !attrs.nil? && attrs.keys.map(&:to_s).include?(key.to_s) }
      setter.call('scheduler_type', 'hotseat')
      yield self if block_given?
    end
  end
  alias_method_chain :initialize, :defaults
end

我在谷歌上看到了以下例子:

  def initialize 
    super
    self.status = ACTIVE unless self.status
  end

and

  def after_initialize 
    return unless new_record?
    self.status = ACTIVE
  end

我也见过有人把它放在迁移中,但我更愿意看到它在模型代码中定义。

是否有一个规范的方法来设置默认值的字段在ActiveRecord模型?


当前回答

这就是构造函数的作用!重写模型的initialize方法。

使用after_initialize方法。

其他回答

Rails 5 +

你可以在你的模型中使用属性方法,例如:

class Account < ApplicationRecord
  attribute :locale, :string, default: 'en'
end

您还可以将lambda传递给默认参数。例子:

attribute :uuid, :string, default: -> { SecureRandom.uuid }

第二个参数是类型,它也可以是一个自定义类型类实例,例如:

attribute :uuid, UuidType.new, default: -> { SecureRandom.uuid }

这就是构造函数的作用!重写模型的initialize方法。

使用after_initialize方法。

class Item < ActiveRecord::Base
  def status
    self[:status] or ACTIVE
  end

  before_save{ self.status ||= ACTIVE }
end

After_initialize方法已弃用,请改用回调方法。

after_initialize :defaults

def defaults
  self.extras||={}
  self.other_stuff||="This stuff"
end

然而,在迁移中使用:default仍然是最干净的方式。

我已经用了一段时间了。

# post.rb
class Post < ApplicationRecord
  attribute :country, :string, default: 'ID'
end