我很想知道为新的ActiveRecord记录设置默认值的方案是否可行。基于一些答案here和this 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
答案 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