Rails 3: encadenamiento de objetos con has_many :a través de asociaciones

I'm trying to get a grasp of how to work with associations in Rails, specifically, when and when not to write explicit SQL code.

In my application, I have four models, which are defined as follows:

class User < ActiveRecord::Base
    has_many :comments
    has_many :geographies
    has_many :communities, through: :geographies

class Comment < ActiveRecord::Base
    belongs_to :user

class Community < ActiveRecord::Base
    has_many :geographies
    has_many :users

class Geography < ActiveRecord::Base
    belongs_to :user
    belongs_to :community

Users can post comments, and are associated to one or more communities through the geography table (the geography table stores user_id y community_id).

I have an index action listing all comments, and I would like to filter by community. Given a comment object, I can get the user object via comment.user, but I can't chain beyond that (i.e., something like comment.user.geography(0).community no funciona).

It seems this object chaining is a key feature of rails, but does it work with has_many :through associations? Given my example, is it possible to get the community object from the comment object by using object chaining, or would I need to write the SQL to get anything other than the user when given the comment object?

preguntado el 01 de julio de 12 a las 00:07

2 Respuestas

Since User is associated with multiple communities, you will need to tell ActiveRecord (or raw SQL) which community you want:

comment.user.communities #=> should give you all the communities

If you don't particularly care for getting all communities and just want to get any community

comment.user.communities.first #=> should give you the first community

But, generally you will be interested in one particular community, based on a condition.

comment.user.communities.where(name: 'Europe') #=> should give you the European community.

Respondido 02 Jul 12, 03:07

I don't think you need the geographies table.

Trata

class Community < ActiveRecord::Base
    has_many :users
end

class User < ActiveRecord::Base
    belongs_to :community
    has_many :comments
end

class Comment < ActiveRecord::Base
    belongs_to :user
end

Then you can access a comment's user's community like @comment.user.community

Respondido 01 Jul 12, 06:07

Thanks, but I need to have the option of a user belonging to multiple communities. I believe the models you describe limit a user to a single community (please correct me if I'm wrong). - ntaj

Oops, you're right. I misread. I think if you just changed the line in your Community.rb to has_many :users, :through => :geographies. Then you could say stuff like @comment.user.communities to get all the users communites, and specify from there - mella

Thanks theButler. Salil was right that I needed to select a community from all of the communities returned (first, last, etc.). Additionally, I can access the community using the chain you described, and it seems to be working even without including the :through :geographies línea. - ntaj

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.