awo*_*gCM 7 mysql sql sql-server join ruby-on-rails
我有以下三个模型加入关系
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
Run Code Online (Sandbox Code Playgroud)
然后在将记录插入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
Run Code Online (Sandbox Code Playgroud)
但在irb控制台中,当我写这篇文章时,
Contribution.joins(:contributor, :book).select("contributors.name, books.name,
contributions.*")
Run Code Online (Sandbox Code Playgroud)
我得到以下输出
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">]>
Run Code Online (Sandbox Code Playgroud)
我没有根据内部联接外键获得任何书名和贡献者的名字.
当我真正想要的时候,我无法理解RAILS SQL语句是如何出错的.
我完全理解的是什么?
Rails模型与与之关联的表映射,因此在查询此模型后,它返回模型对象,在这种情况下是Contribution没有其他模型属性的模型,以实现您希望将查询编写为
contributions = Contribution.joins(:contributor, :book).select("contributors.name
as c_name, books.name as b_name, contributions.*")
Run Code Online (Sandbox Code Playgroud)
返回的结果将是Contributions数组,并且可以通过属性b_name获得结果的书名
contributions.last.b_name
Run Code Online (Sandbox Code Playgroud)
注意:根据您将如何使用查询结果,您必须在两者之间进行选择joins,includes您可以阅读此处