2010-10-08 73 views
2

我工作的Rails项目时遇到用下面加入了一些问题:Rails的连接表问题

@page = Page.find(params[:id], :joins => "LEFT JOIN page_translations ON page_translations.page_id = pages.id") 

出于某种原因,它只能拉回从页表的一切。

这里是我的第

class Page < ActiveRecord::Base 
    has_many :users_pages 
    has_many :users, :through => :users_pages 
    has_many :page_translations 
    has_many :categories 
    accepts_nested_attributes_for :page_translations 
    accepts_nested_attributes_for :categories 
end 

模型这里是我的PageTranslation

class PageTranslation < ActiveRecord::Base 
    belongs_to :pages 
end 

预先感谢所有帮助典范!

编辑(@thenduks)

日志运行两个单独的查询:

Page Load (0.5ms) SELECT `pages`.* FROM `pages` WHERE (`pages`.`id` = 1) LIMIT 1 

PageTranslation Load (0.5ms) SELECT `page_translations`.* FROM `page_translations` WHERE (`page_translations`.page_id = 1) 

这里是我的控制器是什么样子:

@page = Page.find(params[:id], :include => :page_translations) 
+0

你在期待什么?当你做page.page_translations时你会得到什么? – 2010-10-09 00:01:20

+0

伙计。我只是想通了!我会在下面更新我的答案... – John 2010-11-01 04:01:54

+0

下面是一个很好的答案相同的问题:http://stackoverflow.com/questions/27523326/when-joining-table-rails-anyway-makes-additional-request-when-accessing - 字段 – 2014-12-17 11:07:54

回答

0

如何:

Page.find(params[:id], :include => :page_translations) 

编辑

好的,所以最近一段时间,ActiveRecord在连接/包含方面的行为似乎已经发生了变化。指南仍然指的是能够通过两个协会来完成这项工作,如has_many :orders, :include => :line_items和类似的...但是包括has_many的记录...在咨询了co-worker之后,我们遇到了some info on the subject。似乎单一的整体查询变得过于复杂和丑陋,并且导致了ActiveRecord为您提供的一些更好的细节和重复的行,这种情况出现问题。

TL; DR:它不能像那样工作。预计有2个查询。

+0

它仍然拉回所有从页表 – dennismonsewicz 2010-10-08 21:01:30

+1

啊,这可能是因为你已经错误地命名了'PageTranslation'中的'belongs_to'。您可能需要'belongs_to:page'。 – rfunduk 2010-10-09 22:59:42

+0

@thenduks,我的模型包含belongs_to:页面,并且我仍然没有得到查询中返回的所有内容的预期结果。这让我难以置信!我的意思很简单,我可以做两个数据库调用,但那不是有效的。 – dennismonsewicz 2010-10-11 03:42:06

2

我被困在这件事情上,浪费了几个小时试图弄清楚。事实证明,使用查询接口的joins方法不会初始化与要连接的表相关的模型。您可以通过查看服务器控制台中的SQL语句或者甚至将ActiveRecord日志记录重定向到Rails控制台中的STDOUT来查看。

我是非常感谢对此感到失望。这似乎不像是如何工作的 - 这当然不是我所期待的。因为它在边缘指南的热切加载部分,所以我期待着它的急切加载。

反正我不能再浪费更多的时间试图弄明白,所以我做了什么,而不是为使用花哨查询界面,简单地建立我的查询,使用to_sql获得SQL我的查询,然后将SQL传递给select_all,后者返回一个散列数组,其中数组中的每个元素(每个散列)表示一行。

例子:

query = Post.joins("LEFT JOIN categories ON post.category_id = categories.id") 
query.select("posts.*, category.category_name") 
con = ActiveRecord::Base.connection 
results = con.select_all(query.to_sql) 

结果:

[{"id": 1, "title": "joins, why have you forsaken me", "category_name": "frustration"},{"id": 2, "title": "pizza", "category_name": "food"}] 

说实话,我还是想知道肯定,如果有可能做到这一点,我们的思维方式它应该工作,或者它的方式应该工作。否则,我认为除了帮助我们构建查询外,没有理由使用joins方法。因此,如果任何Rails的专家知道如何使用joins来填充与这些表相关的模型,请让我(我们)知道!

无论如何,我希望这可以帮助你现在继续前进。


UPDATE:所以我觉得我想通了。我偶然发现了这个blog post。事实证明,当使用查询接口的joins方法时,Rails实际上会将您从连接表中选择的列添加为要连接的模型的属性方法

使用上面的同一个例子,我实际上可以通过简单地调用post.category_name访问每个帖子的category_name#$%!令人难以置信的简单,但没有任何文档!

这一次是:

query = Post.joins("LEFT JOIN categories ON post.category_id = categories.id") 
query.select("posts.*, category.category_name") 
posts = query.all 

# access a post's category name 
puts posts[0].category_name 

# this is what I thought I would be able to do 
# without Rails making another query to the database 
puts posts[0].category.category_name 

我希望这有助于! :)

+0

感谢上page_translations您回复芽!这很有道理! – dennismonsewicz 2010-10-11 03:40:04

+0

没有问题。很高兴我能帮上忙。 =) – John 2010-10-12 18:05:51

+0

在我的原始帖子结尾添加了更新。一探究竟。 – John 2010-11-01 04:18:03