views:

199

answers:

1

I've got the following situation setup to model a Customer with multiple addresses and a reference table for the type of address. The data model is Customer - Address : many to many relationship, represented with a join table called 'Location'.
LocationType - Location : one to many, so that a locationtype (eg 'work', 'home') can have many associations to a Location.

What i'm trying to achieve is the ability to simply locate all the 'work' addresses for a customer, or the 'delivery' addresses. Whilst avoiding having the text duplicated in the join table Location

The model(s) look like:

class Address < ActiveRecord::Base
  has_many :locations  
  has_many :customers, :through => :locations  
end

class Customer < ActiveRecord::Base  
   has_many :locations  
   has_many :addresses, :through => :locations do  
   def special_location(loc)  
    find :all, :conditions => ['addr_type == ?', loc]  
   end  
  end  
end 

class Location < ActiveRecord::Base
    belongs_to :address
    belongs_to :customer
    belongs_to :locationtype
end

class LocationType < ActiveRecord::Base
    has_many :locations
end

This works ok for the simple cases of :

@customer = Customer.find(1)  
@customer.addresses   # return all addresses

And with the 'special helper method' of special_location("string") I can achieve the result. What I wanted to find out is how I could achieve the same via the use of the additional reference table (LocationType)
Something along the lines of

@customer.addresses.find_locationtype("work")
+1  A: 

You can add some tables to be joined in the select request.

def find_locationtype(type)
    find :all, :conditions => ['location_types.name = ?', type], :joins => :location, :locationtype
end

When you do customer.find_locationtype('work'), the generated query will join the tables location and locationtype. So you'll have access to every field from these two tables and be able to add conditions on them.

Damien MATHIEU
Is this method added to the model or the controller ? It makes sense to have it on the model, as that is the source of information being requested
Grant Sayer
Of course it's in the model. It's logic ;)
Damien MATHIEU