Rails 4中has_many中的静态范围

Posted

技术标签:

【中文标题】Rails 4中has_many中的静态范围【英文标题】:Static scope inside has_many in Rails 4 【发布时间】:2016-11-02 17:20:33 【问题描述】:

我遇到以下问题。我想在模型中设置一定数量的 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_objectssome_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 关系中设置静态范围?

【问题讨论】:

【参考方案1】:

你可以在这里使用Hash#each_pair

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

【讨论】:

是的,这行得通!这和 ArtOfCode 的答案都有效,尽管我认为这个解决方案稍微优雅一些​​。我不知道为什么。这个循环和我使用的循环有什么区别?我会说你最终会遇到同样的问题,但由于某种原因,这行得通,而我的代码却没有。呃,好吧。谢谢! :) @KobusPost 我现在睡着了,用手机打字,但我明天会找时间检查并解释你的那个有什么问题(我应该承认 -我从来没有在 Ruby 中使用过for 循环,甚至一次都没有...... :))【参考方案2】:

这行得通吗?我还没有测试过,但理论上是你访问的是你想要的特定键名,而不是最后一个已知的键名。

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

【讨论】:

以上是关于Rails 4中has_many中的静态范围的主要内容,如果未能解决你的问题,请参考以下文章

Rails 中的 has_many 关联迁移

获取 STI 中的记录以获取 rails 4 中的空 has_many 记录

has_many 中 :unique => true/Distinct 选项的问题,通过关联/命名范围(Rails)

Rails范围过滤元素没有has_many关联元素

Has_many:通过 Rails 4 实例变量不起作用

如何在复杂的Rails has_many范围内进行外连接?