跳至内容 跳至搜索

Active Record 存储

Store 为序列化提供了轻量级的包装器,用于将哈希存储在一个单独的列中。当您不关心在单个记录的上下文中查询存储时,它就像一个简单的键值存储烘焙到您的记录中。

然后您可以声明对该存储的访问器,这些访问器可以像模型的任何其他属性一样访问。这对于轻松地将存储键公开到表单或其他已经围绕仅访问模型上的属性构建的地方非常有用。

每个访问器都带有脏跟踪方法(key_changed?key_waskey_change)以及访问上次保存时所做更改的方法(saved_change_to_key?saved_change_to_keykey_before_last_save)。

注意:访问器没有 key_will_change! 方法,请改用 store_will_change!

确保您将用于序列化存储的数据库列声明为文本,以便有足够的空间。

您可以设置自定义编码器,将序列化属性编码/解码到/从不同的格式。JSON、YAML、Marshal 在开箱即用时受支持。通常,它可以是提供 loaddump 的任何包装器。

注意:如果您使用的是结构化的数据库数据类型(例如 PostgreSQL hstore/json、MySQL 5.7+ json 或 SQLite 3.38+ json),则不需要 .store 提供的序列化。只需使用 .store_accessor 来生成访问器方法即可。请注意,这些列使用字符串键的哈希,不允许使用符号进行访问。

注意:默认验证(除了 uniqueness)将起作用。例如,如果您想使用 hstore 检查 uniqueness,则需要使用自定义验证来处理它。

示例

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
命名空间
方法
R
W

属性

[RW] local_stored_attributes

实例私有方法

read_store_attribute(store_attribute, key)

# 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

write_store_attribute(store_attribute, key, value)

# 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