使用新的ActiveRecord :: Store进行序列化,the docs给出了以下示例实现:
class User < ActiveRecord::Base
store :settings, accessors: [ :color, :homepage ]
end
是否可以使用默认值声明属性,类似于:
store :settings, accessors: { color: 'blue', homepage: 'rubyonrails.org' }
答案 0 :(得分:17)
不,没有办法在store
通话中提供默认值。 store
macro非常简单:
def store(store_attribute, options = {})
serialize store_attribute, Hash
store_accessor(store_attribute, options[:accessors]) if options.has_key? :accessors
end
并且所有store_accessor
都会遍历:accessors
并为每个创建accessor和mutator方法。如果您尝试使用带有:accessors
的哈希值,您最终会向store
添加一些您不想要的内容。
如果您想提供默认值,那么您可以使用after_initialize
挂钩:
class User < ActiveRecord::Base
store :settings, accessors: [ :color, :homepage ]
after_initialize :initialize_defaults, :if => :new_record?
private
def initialize_defaults
self.color = 'blue' unless(color_changed?)
self.homepage = 'rubyonrails.org' unless(homepage_changed?)
end
end
答案 1 :(得分:2)
我也想解决这个问题并最终为Storext做出贡献:
class Book < ActiveRecord::Base
include Storext.model
# You can define attributes on the :data hstore column like this:
store_attributes :data do
author String
title String, default: "Great Voyage"
available Boolean, default: true
copies Integer, default: 0
end
end
答案 2 :(得分:1)
尝试使用https://github.com/byroot/activerecord-typedstore gem。它允许您设置默认值,使用验证结束其他。
答案 3 :(得分:0)
这是我刚刚一起解决这个问题的原因:
# migration
def change
add_column :my_objects, :settings, :text
end
# app/models/concerns/settings_accessors_with_defaults.rb
module SettingsAccessorsWithDefaults
extend ActiveSupport::Concern
included do
serialize :settings, Hash
cattr_reader :default_settings
end
def settings
self.class.default_settings.merge(self[:settings])
end
def restore_setting_to_default(key)
self[:settings].delete key
end
module ClassMethods
def load_default_settings(accessors_and_values)
self.class_variable_set '@@default_settings', accessors_and_values
self.default_settings.keys.each do |key|
define_method("#{key}=") do |value|
self[:settings][key.to_sym] = value
end
define_method(key) do
self.settings[key.to_sym]
end
end
end
end
end
# app/models/my_object.rb
include SettingsAccessorsWithDefaults
load_default_settings(
attribute_1: 'default_value',
attribute_2: 'default_value_2'
)
validates :attribute_1, presence: true
irb(main):004:0> MyObject.default_settings
=> {:attribute_1=>'default_value', :attribute_2=>'default_value_2'}
irb(main):005:0> m = MyObject.last
=> #<MyObject ..., settings: {}>
irb(main):005:0> m.settings
=> {:attribute_1=>'default_value', :attribute_2=>'default_value_2'}
irb(main):007:0> m.attribute_1 = 'foo'
=> "foo"
irb(main):008:0> m.settings
=> {:attribute_1=>"foo", :attribute_2=>'default_value_2'}
irb(main):009:0> m
=> #<MyObject ..., settings: {:attribute_1=>"foo"}>
答案 4 :(得分:0)
以下代码的优点是不会在每个用户记录上保存默认值,从而减少了数据库存储使用量,并且在您要更改默认值时很容易
{{1}}