1

Is there a way to use two values in an association to restrict the data set instead of only one?

I have an has_many association of model Nyaw in a model Foo, which should be mapped using two values instead of just one.

I tried the following code, but it seems to fail to undefined method 'another_id' for #<Nyaw::ActiveRecord_Relation:0x00000003ee6f80> (NoMethodError) error:

class Foo < ActiveRecord::Base
  has_many :nyaws, -> { where "another_id = ?", self.another_id }
end

self.another_id would be a value from the row of Foo model, which for I’ve called the association. For example, foo.nyaws where foo is single row.

In terms of SQL, this is something like SELECT * FROM foos LEFT JOIN nyaws ON foos.nyaw_id = nyaws.id AND foos.random_id = nyaws.something_else. So I basically want to be able to add that part after AND to each query done when someone calls the association.

There seems to be some suggestions around, but all official information mentions only hardcoded values, but nothing about using values from the model where the association is defined at.

Closest I’ve found is something like scope :with_company_id, lambda {|id| joins(:server).where('server.company_id = ?', id) }, but this would only work with a scope that would be used like a class normal method.

Community
  • 1
  • 1
Smar
  • 8,109
  • 3
  • 36
  • 48
  • what do you expect `self.another_id` to return? Do you realize, that `self` is class in that case? – Andrey Deineko Feb 16 '16 at 13:26
  • @AndreyDeineko: It should be the value from `Foo` model. I know it does not work, I gave it as an example of what I’ve tried, and to illustrate what I want to achieve with pseudo-ish code. – Smar Feb 16 '16 at 13:27
  • `value from Foo model` is blurry. is that an class attribute or the model's table column? – Andrey Deineko Feb 16 '16 at 13:28
  • Ah yes sorry, model’s table column. With the association, there will be a row of `Foo`, which for the association is called to, so I’d expect I should be able to use the value from that row in the association comparison. Especially since there already is `primary_key = foreign_id` condition by default. – Smar Feb 16 '16 at 13:30

1 Answers1

0

I went around the problem and created plain method to mimic the has_many for our needs, as following:

class Foo < ActiveRecord::Base
  # Instead of has_many :nyaws, -> { where "another_id = ?", self.another_id }
  def nyaws
    Nyaw.where([ "id = ? AND another_id = ?", self.nyaw_id, self.another_id ])
  end
end
Smar
  • 8,109
  • 3
  • 36
  • 48
  • What is the reason why `has_many` doesn’t work like I expected, I don’t know, and I don’t really know if I should go to open a feature request to upstream about this. Internally the scope is wrapped so that I can’t leak data from the model to the scope in any way, so I’d need to do some really fragile monkey patching, so I’ll use this to avoid it for now. – Smar Feb 17 '16 at 11:32
  • Also this does not exactly answer to my question, so I’m not sure whether I should accept this one as answer. Opinions? – Smar Feb 17 '16 at 11:33