How do I access records from a 2 level nested model
I have 3 models User,Listing and Message. What I want is for an authenticated user to have many listings. The listings then can have multiple messages. So the messages are tied to the user through the listing model. I am able to get a users listings but not able to get the users messages which he owns through the listings. Here are the associations that I currently have.
class User < ActiveRecord::Base
has_many :listings, :dependent => :destroy
end
class Listing < ActiveRecord::Base
belongs_to :user
has_many :messages
end
class Message < ActiveRecord::Base
belongs_to :listing
end
To create a message I simply do this;
@listing = Listing.find(params[:listing_id])
@message = @listing.messages.build(params[:message])
And getting the user's listing i have this;
@user_listings = Listing.user_listings(current_user)
But getting the messages tied to the user's listings proves to be elusive. What am I doing wrong or how do I go开发者_如何转开发 about this? help appreciated.
Still not sure where user_listings comes from but why not this:
@user = User.find(params[:user_id], :include => {:listings => :messages})
@user.listings.each do |listing|
listing.messages.each do |message|
#or
@user.listings.collect(&:messages).each do |message|
#or (just read about using authenticated user so the same as above like this
current_user.listings(:all, :include => :messages)...
Include prefetches all the listings' associated messages in one query in order that they're not fetched in the loop causing n+1 querying.
----------
Or another approach, if you don't need the listings data.
#messages.rb
def self.user_messages user_id
find(:all, :joins => :listings, :conditions => ["listings.user_id = ?", user_id])
#with pagination
def self.user_messages user_id, page
paginate(:all, :joins => :listings,
:conditions => ["listings.user_id = ?", user_id],
:per_page => 10, :page => page)
updated regarding your comment.
You may want to just add has_many :messages to the user class as well and add a user_id column to Message. Then you could just do current_user.messages
How about something like this:
class User < ActiveRecord::Base
has_many :listings, :dependent => :destroy
has_many :listing_messages, :through => :listings
That way you dont have to "tie" the messages with the user because it is always accessed through the listing association:
current_user.listing_messages.all
Or have I misunderstood your question?
If you have current_user pulled already. You can just access listings directly by calling
current_user.listings
instead of
@user_listings = Listing.user_listings(current_user)
精彩评论