0

导轨 3.1,红宝石 1.9.2

我正在尝试将 Railscasts 第 345 集 (HSTORE) 改编为我正在构建的应用程序——这个问题不是以 HSTORE 为中心的......因为如果我正在序列化 Properties 哈希,我也会遇到它。

这是我有疑问的代码:

Class Product < ActiveRecord::Base

has_many :properties

%w[author rating runtime].each do |key| #  *****--> PLEASE SEE BELOW!
  attr_accessible key
  scope "has_#{key}", lambda { |value| where("properties @> (? => ?)", key, value) }

  define_method(key) do
    properties && properties[key]
  end

  define_method("#{key}=") do |value|
    self.properties = (properties || {}).merge(key => value)
  end
end

*现在,这里是转折点。产品类别具有许多由管理员在创建时分配的属性。这是在一个名为 Property 的连接模型中完成的。

因此,我想搜索一个名为 Property 的已连接的 has_many 模型,而不是属性数组,并让数组填充属性 ID 的集合。

我尝试将声明的 %w[author rating runtime] 数组替换为

self.properties.collect{ |property| "property_#{property.id}" }.each do |key|

但这不起作用!我在属性关系上得到一个未定义的方法错误(我认为这是因为模型尚未实例化?)我对编程相当陌生,对元编程一无所知。

编辑 - 我试图将所有这些移到 after_find 钩子中,但这也不起作用(以及其他几十次不成功的尝试。)所以迷失了......

任何帮助是极大的赞赏!

4

1 回答 1

0

好吧,经过几天的黑客攻击,我想我终于弄明白了。

非常感谢有关此解决方案的“声音”程度的任何和所有小齿轮!

简而言之,我所做的只是将上面的代码块(以 % 符号开头)包装成这样的方法:

def dynamic_accessible_and_setters(*details)
  details.each do |key| # I placed the details variable here instead of the %w[]
    attr_accessible key
    scope "has_#{key}", lambda { |value| where("properties @> (? => ?)", key, value) }

    define_method(key) do
      properties && properties[key]
    end

    define_method("#{key}=") do |value|
      self.properties = (properties || {}).merge(key => value)
    end
  end
end

然后,在控制器中,我只是从类中调用方法并分配属性数组:

def edit
  PRODUCT.dynamic_accessible_and_setters("author", "rating", "runtime")
  ...
end

现在我已经为类的每个实例动态构建了 getter、setter 和 attr_accessible(或者,我认为?!)

我希望这可以帮助别人!现在来看看多次数据库写入与序列化和一次写入的性能权衡。

于 2012-05-14T18:49:09.437 回答