我有以下三个模型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
然后在将记录插入Contribution连接模型之后,我决定要对此模型进行查询以检索所有书籍和贡献者名称作为结果查询,如以下SQL等效项
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
但在irb控制台中,当我写这篇文章时,
Contribution.joins(:contributor, :book).select("contributors.name, books.name,
contributions.*")
我得到以下输出
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">]>
我没有根据内部联接外键获得任何书名和贡献者的名字。
当我真正想要的时候,我无法理解RAILS SQL语句是如何出错的。
我完全理解的是什么?
答案 0 :(得分:6)
Rails模型与与之关联的表进行映射,因此在查询此模型后,它返回模型对象,在这种情况下为Contribution
模型,其中没有其他模型属性,以实现您想要的效果需要将您的查询编写为
contributions = Contribution.joins(:contributor, :book).select("contributors.name
as c_name, books.name as b_name, contributions.*")
返回的结果将是Contributions数组,其中一个可以通过属性b_name从
获取结果的书名contributions.last.b_name
注意:根据您要使用查询结果的方式,您必须在joins
和includes
之间进行选择,您可以阅读Here
答案 1 :(得分:0)
是的,在查询的回复中你不会看到任何书名,但是如果你得到[0] .book.name,你会看到书的名字。它只是在显示的结果中不可见,但你可以通过访问它来获得它。
正如sat所说,你可以使用include,这样当你访问book table时它就不会产生额外的查询,但是在join中它会为每次访问book table做额外的DB调用。