Reputation: 154
I'm having the following issue. I want to set a certain amount of has_many relations in a model, with names taken from a passed array (or in this case, the keys of a hash). Like this:
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
This results in two has_many relations: some_object.foo_objects
& some_object.bar_objects
. Both have a specific class_name and a specific scope, set in the where clause in the lambda. However, because the scope is a lambda it gets the key_name in the where clause dynamically. This is the last known key_name variable, which is the last one in the loop, in this case 'bar'. So both foo_objects
and bar_objects
return a set of objects scoped with where(var: "bar")
.
Usually the lambda makes a great way to pass in dynamic scopes in has_many relations, but in this case I don't really need it. Is it possible to set a static scope inside a has_many relation?
Upvotes: 2
Views: 101
Reputation: 52357
You might use Hash#each_pair
here:
object_class_names.each_pair do |key_name, klass|
has_many :"#{key_name}_objects", -> { where(var: key_name) }, class_name: klass.to_s
end
Upvotes: 1
Reputation: 5712
Does this work? I haven't tested it, but the theory is that you're accessing the specific key name you want, rather than the last-known key name.
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
Upvotes: 1