Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

rails has_many :through has_many :through

I'm wondering to what extent I can use associations in Rails. Take into consideration the following:

class User < ActiveRecord::Base
    has_one :provider
    has_many :businesses, :through => :provider
end

class Provider < ActiveRecord::Base
    has_many :businesses
    has_many :bids, :through => :businesses
    belongs_to :user
end

class Business < ActiveRecord::Base
    has_many :bids
    belongs_to :provider
end

class Bid < ActiveRecord::Base
    belongs_to :business
end

I am able to set up these nifty shortcuts like User.businesses and Provider.bids but what about doing something like User.bids? Is it possible to associate an association, so to speak?

like image 215
bloudermilk Avatar asked Jan 12 '10 20:01

bloudermilk


2 Answers

This is entirely possible, but needs a little extra work. The following model definitions used in conjunction with the nested_has_many plugin you can fetch all bids belonging to a user with just @user.bids

class User < ActiveRecord::Base
    has_one :provider
    has_many :businesses, :through => :provider
    has_many :bids, :through => :businesses
end

class Provider < ActiveRecord::Base
    has_many :businesses
    has_many :bids, :through => :businesses
    belongs_to :user
end

class Business < ActiveRecord::Base
    has_many :bids
    belongs_to :provider
end

class Bid < ActiveRecord::Base
    belongs_to :business
end

However getting a user from a bid will take a more work.

like image 150
EmFi Avatar answered Sep 29 '22 14:09

EmFi


If you just want to fetch the records, why not use use #delegate? It works just fine, at least in the scenario you've described.

class User < ActiveRecord::Base
    has_one :provider
    delegate :bids, :to => :provider
end

class Provider < ActiveRecord::Base
    has_many :businesses
    has_many :bids, :through => :businesses
    belongs_to :user
end

class Business < ActiveRecord::Base
    has_many :bids
    belongs_to :provider
end

class Bid < ActiveRecord::Base
    belongs_to :business
end

Although in my not-so-humble-opinion you should just chain the methods because it's more straightforward, and you're no longer achieving the performance boost unless you go with some crazy custom SQL as tadman says.

like image 33
tfwright Avatar answered Sep 29 '22 13:09

tfwright