views:

39

answers:

3

hello

I would like joining more three tables in rails 3

my code

class offer < ActiveRecord::Base 

  belongs_to :user
  has_many :usercomments, :dependent => :destroy
  has_many :comments, :through => :usercomments, :dependent => :destroy

end
class User < ActiveRecord::Base

  has_many :usercomments, :dependent =>:destroy
  has_many :comments,:through => :usercomments, :dependent => :destroy
  has_many :offers, :dependent => :destroy

end 
class Usercomment < ActiveRecord::Base

  belongs_to :user
  belongs_to :comment
  belongs_to :offer

end
class Comment < ActiveRecord::Base

  has_one :usercomment, :dependent => :destroy
  has_one :offer, :through => :usercomments
  has_one :user, :through => :usercomments

end

schema

create_table "offers", :force => true do |t|
  t.integer  "step_id"  
  t.integer  "user_id"  
  t.date     "offerdate"  
end
create_table "users", :force => true do |t|  
  t.string   "firstname",            :limit => 100, :default => ""  
  t.string   "lastname",             :limit => 100, :default => ""  
  t.string   "email",                :limit => 100  
end
create_table "usercomments", :force => true do |t|
  t.integer  "user_id"
  t.integer  "airoffer_id"
  t.integer  "comment_id"
  t.boolean  "shared"
end 
create_table "comments", :force => true do |t|
  t.string   "comment" 
  t.datetime "created_at"
  t.datetime "updated_at"
end

index.html.erb

 <% airoffers.each do |airoffer| %>

???

 <% end %> 

and in my html.erb page i would like find a comment for an offer (offer_id) and an user (user_id).

Could you help me ? thank you and sorry for my english expression, i am french.

A: 

This will give you an array of comments for User#123 en Offer#456

UserComment.find(:all, :conditions => {
  :user_id  => 123,
  :offer_id => 456
}).collect(&:comment)
Ariejan
Thank you for answer, but there are no solution to use associate model properties of rails ?
Yes, there probably are, but in this example you don't have to touch the `users` table at all. All other solution add `users` to the join, which will slow down your query. This may seem insignificant now but when the size of your data grows and the number of queries goes up, you'll thank me.
Ariejan
exemple offers.user.comment
ok Ariejan, i understand
A: 

It looks to me like what you want is:

class User < ActiveRecord::Base
   has_many :comments
   has_many :offers
end

class Offer < ActiveRecord::Base
   has_many :comments
   belongs_to :user
end

class Comment < ActiveRecord::Base
  belongs_to :user
  belongs_to :offer
end

If you want all the Comments that belong to a specific User and a specific Offer, just do Comment.where(:user_id => # :offer_id => #) and pass in the User and Offer you want.

Does this help?

Adam Tanner
Yes Adam, it's true. My analyze is wrong. The user id must be in the comment model, with the offer id i think. Thank you help.
A: 

Finally, i chose this solution

my code

class offer < ActiveRecord::Base 

  belongs_to :user
  has_many :comments, :dependent => :destroy, :order => "updated_at DESC"

end
class User < ActiveRecord::Base

  has_many :comments,:dependent => :destroy
  has_many :offers, :dependent => :destroy

end 
class Comment < ActiveRecord::Base

  has_one :user, :dependent => :destroy
  has_one :airoffer, :dependent => :destroy

end

schema

create_table "offers", :force => true do |t|
  t.integer  "user_id"  
  t.date     "offerdate"  
end
create_table "users", :force => true do |t|  
  t.string   "firstname",            :limit => 100, :default => ""  
  t.string   "lastname",             :limit => 100, :default => ""  
  t.string   "email",                :limit => 100  
end
create_table "comments", :force => true do |t|
  t.integer  "user_id"
  t.integer  "offer_id"  
  t.string   "comment" 
  t.datetime "created_at"
  t.datetime "updated_at"
end

in offer_controller.rb

@offers = User.find(current_user.id).offers.includes(:comments)

and in my index.html.erb

<% @offers.each do |airoffer| %>

<% airoffer.comments[0].comment %>

<% end %>

I know, it's not the better solution, but in the first time i will use it.