ActiveRecord:用于在新记录上设置默认属性的方案

时间:2013-04-30 16:48:12

标签: ruby-on-rails activerecord

我很想知道为新的ActiveRecord记录设置默认值的方案是否可行。基于一些答案herethis post on setting attributes,我想出了类似的结果:

class Taco < ActiveRecord::Base

  DEFAULT_ATTR = {spice_level: 4}

  before_save do |taco|
    if new_record?
      DEFAULT_ATTR.each do |k,v|
        taco[k] ||= v
      end 
    end 
  end 

end

对于偏执狂,常量也可用于设置迁移中的默认值:

class CreateTacos  < ActiveRecord::Migration

  def defaults
    Taco::DEFAULT_ATTR
  end 

  def change
    add_column :tacos, :spice_level, :integer, :default => defaults[:spice_level]
  end 
end

什么是有用的(直到有人指出我忽略了一些明显的方面!)是这个方案是作为回调内置在ActiveRecord中,ala before_save(类似“new_record_defaults”)。您可以覆盖该方法并返回symbol =&gt;的哈希值默认对,甚至偏执的迁移代码也可以利用它。

我仍然是Rails的新手,所以我准备被告知已经存在的方案或为什么这是一个愚蠢的想法,但欢迎反馈。 :)

更新:根据安东格里戈里耶夫的回答,我认为属性默认宝石是要走的路。对于后代,这里有一个额外的关注点based on the author's original,用于访问创建的默认值:

module ActiveRecord
  module AttributesWithDefaultsAccessor
    extend ActiveSupport::Concern
    def all_defaults
      defaults = {}
      self.private_methods.each do |method|
        if method =~ /^__eval_attr_default_for_(.+)$/
          defaults[$1.to_sym] = self.send(method)
        end
      end
      defaults
    end
  end
  class Base
    include AttributesWithDefaultsAccessor
  end
end

2 个答案:

答案 0 :(得分:1)

您可以使用此gem https://github.com/bsm/attribute-defaults来设置属性默认值

答案 1 :(得分:0)

我更希望将此逻辑保留在应用程序级别而不是数据库级别(通过迁移)。

在应用程序级别,这只是覆盖属性

class Taco < ActiveRecord::Base
  def spice_level
    read_attribute(:spice_level) || 4
  end
end

基本的是,如果你将这个属性设置为5,则为5.如果不是,则为4。

关于覆盖属性的参考: http://api.rubyonrails.org/classes/ActiveRecord/Base.html#label-Overwriting+default+accessors