Topic: Guilty by association!

I'm writing a web application to manage community service opportunities. There are 4 models: Location, User, State, and Opportunity. Every user has a location (where they live) and every opportunity has one or more locations (the places that opportunity is available at). Every location has a state. Is there a way, through built in RoR mechanics, to get what users live in a certain state? I had experimented with putting "has_many :through=> :locations" but with no luck (HasManyThroughSourceAssociationMacroError).

This is what I had:

class State < ActiveRecord::Base
  has_many :locations
  has_many :users, :through=> :locations
end

class Location < ActiveRecord::Base
   has_and_belongs_to_many :opportunities
   has_one :user
   belongs_to :state
end

class User < ActiveRecord::Base
   belongs_to :location
end


Is there something wrong with my associations? My database looks (roughly) like this:

   create_table "locations", :force => true do |t|
      t.column "state_id", :integer
   end
 
   create_table "locations_opportunities", :force => true do |t|
     t.column "location_id", :integer
     t.column "opportunity_id", :integer
   end
 
   create_table "opportunities", :force => true do |t|
 
   end
 
   create_table "states", :force => true do |t|
 
   end
 
   create_table "users", :force => true do |t|
     t.column "location_id", :integer
   end

Thank you for your time, I appreciate it. Any feedback would be highly valued. Thanks again!
(Note: There was a similar post by me in another forum, but I deleted it and elaborated here)

Last edited by octoberdan (2007-01-16 11:27:09)

Re: Guilty by association!

I want to be able to State.find(1).users and get a list of users in that state

Re: Guilty by association!

I switched to edge rails and now get the following error

>> State.find(1).users
ActiveRecord::HasManyThroughSourceAssociationMacroError: Invalid source reflection macro :has_one for has_many :users, :through => :locations.  Use :source to specify the source reflection.
        from ./script/../config/../config/../vendor/rails/activerecord/lib/active_record/reflection.rb:187:in `check_validity!'
        from ./script/../config/../config/../vendor/rails/activerecord/lib/active_record/associations/has_many_through_association.rb:6:in `initialize'
        from ./script/../config/../config/../vendor/rails/activerecord/lib/active_record/associations.rb:990:in `new'
        from ./script/../config/../config/../vendor/rails/activerecord/lib/active_record/associations.rb:990:in `users'
        from (irb):2

Re: Guilty by association!

Does this have to do with http://dev.rubyonrails.org/ticket/4996 ?

Re: Guilty by association!

I tried switching the relationship between location and user to has_and_belongs_to_many and adding the join table (locations_users), but "ActiveRecord::HasManyThroughSourceAssociationMacroError: Invalid source reflection macro :has_and_belongs_to_many for has_many :users, :through => :locations.  Use :source to specify the source reflection."

Last edited by octoberdan (2007-01-16 12:34:29)

Re: Guilty by association!

Well, I got this working, but I had to make some changes that didn't fit my design. I switched the has_one/belongs_to relationship. Location now belongs_to user... even though that wont always be the case. State.find(1).users now works.. wooo... was it worth it? Perhaps I'll elect "spoke persons" or something for each location matched with an opportunity. *sigh* *shrug*