module ActiveRecord::Store
Хранилище Active Record
Store предоставляет тонкий обертка над serialize для хранения хэшей в одном столбце. Это как простое хранилище ключ/значение, встроенное в вашу запись, когда вам не нужно возможность запроса этого хранилища вне контекста одной записи.
Затем вы можете объявить аксессоры к этому хранилищу, которые будут доступны, как и любой другой атрибут модели. Это очень полезно для легкого отображения ключей хранилища в форме или в других местах, которые уже построены вокруг доступа к атрибутам модели.
Каждый аксессор поставляется с методами отслеживания изменений (key_changed?, key_was и key_change) и методами доступа к изменениям, внесенным во время последнего сохранения (saved_change_to_key?, saved_change_to_key и key_before_last_save).
ПРИМЕЧАНИЕ: Нет метода key_will_change! для аксессоров, используйте store_will_change! вместо него.
Убедитесь, что вы объявляете столбец базы данных, используемый для сериализованного хранилища, как текст, чтобы было достаточно места.
Вы можете установить пользовательский кодер для кодирования/декодирования ваших сериализованных атрибутов в/из различных форматов. JSON, YAML, Marshal поддерживаются из коробки. Как правило, это может быть любой обертка, которая предоставляет load и dump.
ПРИМЕЧАНИЕ: Если вы используете структурированные типы данных базы данных (например, PostgreSQL hstore/json, MySQL 5.7+ json, или SQLite 3.38+ json), нет необходимости в сериализации, предоставляемой .store. Просто используйте .store_accessor вместо этого для генерации методов аксессоров. Имейте в виду, что эти столбцы используют хэш с ключами-строками и не позволяют доступа с использованием символов.
ПРИМЕЧАНИЕ: По умолчанию валидации, за исключением uniqueness, будут работать. Например, если вы хотите проверить uniqueness с hstore, вам потребуется использовать пользовательскую валидацию для её обработки.
Примеры:
class User < ActiveRecord::Base store :settings, accessors: [ :color, :homepage ], coder: JSON store :parent, accessors: [ :name ], coder: JSON, prefix: true store :spouse, accessors: [ :name ], coder: JSON, prefix: :partner store :settings, accessors: [ :two_factor_auth ], suffix: true store :settings, accessors: [ :login_retry ], suffix: :config end u = User.new(color: 'black', homepage: '37signals.com', parent_name: 'Mary', partner_name: 'Lily') u.color # Accessor stored attribute u.parent_name # Accessor stored attribute with prefix u.partner_name # Accessor stored attribute with custom prefix u.two_factor_auth_settings # Accessor stored attribute with suffix u.login_retry_config # Accessor stored attribute with custom suffix u.settings[:country] = 'Denmark' # Any attribute, even if not specified with an accessor # There is no difference between strings and symbols for accessing custom attributes u.settings[:country] # => 'Denmark' u.settings['country'] # => 'Denmark' # Dirty tracking u.color = 'green' u.color_changed? # => true u.color_was # => 'black' u.color_change # => ['black', 'green'] # Add additional accessors to an existing store through store_accessor class SuperUser < User store_accessor :settings, :privileges, :servants store_accessor :parent, :birthday, prefix: true store_accessor :settings, :secret_question, suffix: :config end
Имена хранимых атрибутов можно получить, используя .stored_attributes.
User.stored_attributes[:settings] # => [:color, :homepage, :two_factor_auth, :login_retry]
Переопределение аксессоров по умолчанию
Все сохранённые значения автоматически доступны через аксессоры объекта Active Record, но иногда вам нужно специализировать это поведение. Это можно сделать, переопределив аксессоры по умолчанию (используя то же имя, что и атрибут) и вызвав super для фактического изменения вещей.
class Song < ActiveRecord::Base
# Uses a stored integer to hold the volume adjustment of the song
store :settings, accessors: [:volume_adjustment]
def volume_adjustment=(decibels)
super(decibels.to_i)
end
def volume_adjustment
super.to_i
end
end
Атрибуты
Приватные методы экземпляра
# File activerecord/lib/active_record/store.rb, line 209 def read_store_attribute(store_attribute, key) # :doc: accessor = store_accessor_for(store_attribute) accessor.read(self, store_attribute, key) end
# File activerecord/lib/active_record/store.rb, line 214 def write_store_attribute(store_attribute, key, value) # :doc: accessor = store_accessor_for(store_attribute) accessor.write(self, store_attribute, key, value) end
© 2004–2021 David Heinemeier Hansson
Licensed under the MIT License.