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?
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With