Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails Join Model select joint columns

I have the following three models join-relationship

class Book < ActiveRecord::Base
  has_many :contributions, :dependent => :destroy
  has_many :contributors, :through => :contributions
end

class Contributor < ActiveRecord::Base
  has_many :contributions, :dependent => :destroy
  has_many :books, :through => :contributions do
    def this_is_my_contribution(book, join_attrs) 
      Contribution.with_scope(:create => join_attrs) {self << book}
    end
  end
 end

class Contribution < ActiveRecord::Base
  belongs_to :book
  belongs_to :contributor
end

Then after inserting records into the Contribution join model, I decided I want to do a query on this model to retrieve all the books and contributors names as a result query as in the following SQL equivalent

SELECT Contributions.*, Contributors.name, Books.name from Contributions 
INNER JOIN Contributors ON Contributors.id = Contributions.contributors_id 
INNER JOIN Books ON Books.id = Contributions.books_id

But in irb console, when I wrote this,

Contribution.joins(:contributor, :book).select("contributors.name, books.name,
  contributions.*")   

I get the following output instead

 Contribution Load (0.8ms)  SELECT contributors.name, books.name, contributions.* FROM
 "contributions" INNER JOIN "contributors" ON "contributors"."id" =
 "contributions"."contributor_id" INNER 
 JOIN "books" ON "books"."id" = "contributions"."book_id"                                                                                                                                          
 => #<ActiveRecord::Relation [#<Contribution id: 1, book_id: 1, contributor_id: 1, role: 
 "author", created_at: "2014-04-04 00:19:15", updated_at: "2014-04-04 00:19:15">, #
 <Contribution id: 2, book_id: 2, contributor_id: 2, role: "Author", created_at: "2014-
 04-05 06:20:34", updated_at: "2014-04-05 06:20:34">]>   

I don't get any book's name and contributor's name based on the inner join foreign keys.

I couldn't understand how RAILS SQL statement be very wrong when that's what I intently want.

What is that I do fully comprehend?

like image 670
awongCM Avatar asked Apr 05 '14 07:04

awongCM


1 Answers

Rails models are mapped with the tables associated with it so after querying this model it returns models object which in this case is Contribution model which doesn't have other models attributes, to achieve what you want you need to write your query as

contributions = Contribution.joins(:contributor, :book).select("contributors.name
  as c_name, books.name as b_name, contributions.*")

returned result will be array of Contributions and one could get book name from result by attribute b_name as

contributions.last.b_name

Note: depending on how you are going to use query results you have to choose between joins and includes you could read Here

like image 172
sat's Avatar answered Sep 16 '22 14:09

sat's