Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Explanation of proxy_association to find unassociated records

I came across some magic today and I am hoping for some help in understanding it so I can write informed code.

In my app, I have three classes:

class Person < ActiveRecord::Base
  has_many :selected_apps
  has_many :app_profiles, through: :selected_apps do
    def unselected(reload=false)
      @unselected_app_profiles = nil if reload
      @unselected_app_profiles ||= proxy_association.owner.app_profile_ids.empty? ?
        AppProfile.all :
        AppProfile.where("id NOT IN (?)", proxy_association.owner.app_profile_ids)
    end
  end
end

class AppProfile < ActiveRecord::Base
end

class SelectedApp < ActiveRecord::Base
  belongs_to :person
  belongs_to :app_profile
end

The above code lets me do person.app_profiles.unselected and get back all of the AppProfiles that are not currently associated with the Person without having to do a lot of SQL work. Brilliant!

My problem is that I don't understand the code - which always leaves me feeling unsettled. I tried trolling through the proxy_association documentation, but it was fairly opaque.

Can anyone provide a reasonably straight-forward explanation and/or a good place to learn more?

like image 395
jvillian Avatar asked Dec 21 '22 22:12

jvillian


1 Answers

Basically, when you call self while extending an association it won't return an Association instance, but instead delegates to to_a.

Try it:

class Person < ActiveRecord::Base
  has_many :app_profiles, through: :selected_apps do
    def test_me
      self
    end
  end
end

Sometimes we need to get to the actual association object while were extending the association itself. Enter the proxy_association method, which will give us the association which contains the owner, target, and reflection attributes.

For reference here is the documentation.

This question provides a simpler use case of proxy_association.owner.

like image 156
Azolo Avatar answered Mar 15 '23 23:03

Azolo