ActiveRecord :: Store со значениями по умолчанию - PullRequest
10 голосов
/ 12 марта 2012

Используя новый ActiveRecord :: Store для сериализации, документы дают следующий пример реализации:

class User < ActiveRecord::Base
  store :settings, accessors: [ :color, :homepage ]
end

Можно ли объявлять атрибуты со значениями по умолчанию, что-то вроде:

store :settings, accessors: { color: 'blue', homepage: 'rubyonrails.org' }

Ответы [ 5 ]

18 голосов
/ 12 марта 2012

Нет, в вызове store невозможно указать значения по умолчанию.Макрос store довольно прост:

def store(store_attribute, options = {})
  serialize store_attribute, Hash
  store_accessor(store_attribute, options[:accessors]) if options.has_key? :accessors
end

И все, что делает store_accessor, это перебирает :accessors и создает методы доступа и мутатора для каждого.Если вы попытаетесь использовать хэш с :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
2 голосов
/ 21 мая 2015

Я тоже хотел решить эту проблему и в итоге помог 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
1 голос
/ 14 июля 2016

попробуйте использовать https://github.com/byroot/activerecord-typedstore драгоценный камень.Позволяет установить значение по умолчанию, использовать проверку и прочее.

0 голосов
/ 19 ноября 2018

Преимущество следующего кода заключается в том, что значения по умолчанию не сохраняются в каждой записи пользователя, что сокращает использование хранилища базы данных и упрощает на случай, если вы хотите изменить значения по умолчанию

class User < ApplicationRecord
  DEFAULT_SETTINGS = { color: 'blue', homepage: 'rubyonrails.org' }

  store :settings, accessors: DEFAULT_SETTINGS.keys

  DEFAULT_SETTINGS.each do |key,value|
    define_method(key) {
      settings[key] or value
    }
  end
end
0 голосов
/ 15 июля 2014

Вот что я только что взломал, чтобы решить эту проблему:

# 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"}>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...