使虚拟属性成为一个哈希的一部分

时间:2013-03-21 21:27:20

标签: ruby-on-rails activerecord

我有一个模型,在数据库中有一个实际列。此列存储为JSON配置字符串。我使用了一堆虚拟属性,我想在这个配置JSON属性中映射。我基本上不想在db中创建一堆束,而是使用这一个JSON属性来包含所有内容。有没有比实现这个目标的def更清洁的方法?

class Device < ActiveRecord::Base
  attr_accessible :configuration
  serialize :configuration, JSON

  attr_accessor :background_color, :title

  # below is ew
  def background_color; self.configuration["background_color"]; end
  def background_color=(value); self.configuration["background_color"] = value; end

  def title; self.configuration["title"]; end
  def title=(value); self.configuration["title"] = value; end
end

理想情况下,我会寻找像attr_maps_to_hash :configuration, [:background_color, :title]这样的东西。这样的事情存在吗?

3 个答案:

答案 0 :(得分:1)

您可以使用ActiveRecord::Store

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

u = User.new(color: 'black', homepage: '37signals.com')
u.color                          # Accessor stored attribute
u.settings[:country] = 'Denmark' # Any attribute, even if not specified with an accessor

# Add additional accessors to an existing store through store_accessor
class SuperUser < User
  store_accessor :settings, :privileges, :servants
end

如果您使用的是PostgreSQL,请查看HStore

答案 1 :(得分:1)

3.2版本的Rails具有内置于ActiveRecord中的键值存储 - 请参阅此处:

Where can i read more about Rails 3.2's Data Store with key-value in textfield?

在您的情况下,您可以使用名为configuration的文本字段,然后执行以下操作:

class Device&lt; AR :: Base的   store:配置,访问者:[:title,:background_color,...] ...

这应该适用于表格等。

答案 2 :(得分:0)

我想到了两种方法。

首先,你可以拥有一个属性数组[:background_color,:title],然后在调用define_method时迭代它们。您将定义两个方法,define(method_name)和define(“#{method_name} =”)。

其次,类似的想法,但使用方法缺失。

def method_missing(method_name, *args, &block)
  ...see if it's a get or set...
  ...do your stuff...
  ...rain dance...
  ...yay...
end