Kobus Post
Kobus Post

Reputation: 154

Static scope inside has_many in Rails 4

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

Answers (2)

Andrey Deineko
Andrey Deineko

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

ArtOfCode
ArtOfCode

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

Related Questions