Rails 4中的has_many内部的静态范围

时间:2016-11-02 17:20:33

标签: ruby-on-rails ruby rails-activerecord

我遇到以下问题。我想在模型中设置一定数量的has_many关系,名称取自传递的数组(或者在这种情况下,是哈希的键)。像这样:

object_class_names = {:foo => FooClass, :bar => BarClass}

for key_name in object_class_names.keys
  has_many  "#{key_name}_objects".to_sym,
            -> {where(var: key_name)},
            :class_name => object_class_names[key_name]
end

这导致两个has_many关系:some_object.foo_objects& some_object.bar_objects。两者都有一个特定的class_name和一个特定的范围,在lambda的where子句中设置。但是,因为范围是lambda,所以它动态地获取where子句中的key_name。这是最后一个已知的key_name变量,它是循环中的最后一个变量,在本例中为“bar”。因此,foo_objectsbar_objects都会返回一组作用于where(var: "bar")的对象。

通常lambda是在has_many关系中传递动态范围的好方法,但在这种情况下我并不需要它。是否可以在has_many关系中设置静态范围?

2 个答案:

答案 0 :(得分:1)

这有用吗?我还没有对它进行过测试,但理论上说你正在访问你想要的特定密钥名称,而不是最后一个已知的密钥名称。

object_class_names.keys.each_with_index do |key_name, index|
  has_many "#{key_name}_objects",
           -> { where(:var => object_class_names.keys[index]) },
           :class_name => object_class_names[key_name]
end

答案 1 :(得分:1)

您可以在此处使用Tasks.Add

object_class_names.each_pair do |key_name, klass|
  has_many :"#{key_name}_objects", -> { where(var: key_name) }, class_name: klass.to_s
end