Ruby on Rails - >元编程 - 基于has_many关系创建attr_accessible属性的动态数组

时间:2012-05-10 17:49:04

标签: ruby-on-rails ruby ruby-on-rails-3 ruby-on-rails-3.1

Rails 3.1,Ruby 1.9.2

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

以下是我对以下问题的代码:

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 [作者评级运行时]数组
self.properties.collect{ |property| "property_#{property.id}" }.each do |key|

但这不起作用!!我在属性关系上得到一个未定义的方法错误(我假设它是因为模型还没有实例化?)我对编程很新,对元编程一无所知。

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

非常感谢任何帮助!

1 个答案:

答案 0 :(得分: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,自定义(或者,我认为?!)

我希望这有助于某人!现在关闭以查看多个数据库写入与序列化和一次写入的性能权衡。