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!.
Убедитесь, что столбец базы данных для сериализованного хранилища имеет тип text, чтобы в нем было достаточно места.
Вы можете задать пользовательский кодировщик для кодирования и декодирования сериализованных атрибутов в разных форматах и из них. JSON, YAML и Marshal поддерживаются из коробки. Как правило, это может быть любая обертка, предоставляющая load и dump.
ПРИМЕЧАНИЕ: Если вы используете структурированные типы данных базы данных (например, hstore/json в PostgreSQL, json в MySQL 5.7+ или json в SQLite 3.38+), сериализация, предоставляемая .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 215 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 220 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.