Rails Join Model选择联合列

时间:2014-04-05 07:47:18

标签: mysql sql ruby-on-rails sql-server join

我有以下三个模型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语句是如何出错的。

我完全理解的是什么?

2 个答案:

答案 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

注意:根据您要使用查询结果的方式,您必须在joinsincludes之间进行选择,您可以阅读Here

答案 1 :(得分:0)

是的,在查询的回复中你不会看到任何书名,但是如果你得到[0] .book.name,你会看到书的名字。它只是在显示的结果中不可见,但你可以通过访问它来获得它。

正如sat所说,你可以使用include,这样当你访问book table时它就不会产生额外的查询,但是在join中它会为每次访问book table做额外的DB调用。