2016-11-02 118 views
2

我遇到以下問題。我想在一個模型中設置一定數量的has_many關係,名稱取自一個通過數組(或者在這種情況下,是一個散列鍵)。就像這樣:Rails 4中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關係中設置一個靜態作用域?

回答

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 
+0

是的,這個作品!這個和ArtOfCode的答案都適用,儘管我認爲這個解決方案稍微更優雅。至於爲什麼,我不知道。這個循環與我使用的循環有什麼區別?我會說你最終會遇到同樣的問題,但出於某種原因,這是有效的,而我的代碼卻沒有。呃,好吧。謝謝! :) –

+0

@KobusPost我現在正在睡着,從手機上打字,但我會盡力找到明天的一個時刻,檢查並解釋你有什麼問題(我應該承認 - 我從來沒有用過' Ruby中的'循環,甚至不是一次.. :)) –

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