2011-12-19 197 views
1

我有两个表(主题和页面)一对多关系。我想添加主题的标准以及页面来解析sql,但是进度非常缓慢,并且经常遇到问题。我是全新的铁轨,请帮助。在科目Ruby on Rails - 如何连接两个表?

class Subject < ActiveRecord::Base 
    has_many :pages 
end 

class Page < ActiveRecord::Base 
    belongs_to :subject 
end 

样本数据,下面列出三列:

id name level 
1 'Math' 1 
6 'Math' 2 
... 

的样本数据中的网页,列出的列如下:

id name     subject_id 
-- -------------------- ---------- 
2 Addition    1 
4 Subtraction    1 
5 Simple Multiplication 6 
6 Simple Division   6 
7 Hard Multiplication  6 
8 Hard Division   6 
9 Elementary Divsion  1 

既然我不知道的主题。我只知道主题名称和级别以及页面名称。下面是我想生成(或类似的东西,会得到相同的结果),在SQL:

select subjects.id, subjects.name, pages.id, pages.name from subjects, pages 
where subjects.id = pages.subject_id 
    and subjects.name = 'Math' 
    and subjects.level = '2' 
    and pages.name like '%Division' ; 

我预计结果拿到两行:

subjects.id  subjects.name pages.id pages.name 
-----------  ------------- -------- ----------- 
6    Math   6   Simple Division 
6    Math   8   Hard Division 

这是一个非常简单的SQL ,但我一直无法得到我想要的铁轨。

Here is my rails console: 

>> subject = Subject.where(:name => 'Math', :level => 2) 
    Subject Load (0.4ms) SELECT `subjects`.* FROM `subjects` WHERE `subjects`.`name` = 'Math' AND `subjects`.`level` = 2 
[#<Subject id: 6, name: "Math", position: 1, visible: true, created_at: "2011-12-17 04:25:54", updated_at: "2011-12-17 04:25:54", level: 2>] 
>> 
>> subject.joins(:pages).where(['pages.name LIKE ?', '%Division']) 
    Subject Load (4.2ms) SELECT `subjects`.* FROM `subjects` INNER JOIN `pages` ON `pages`.`subject_id` = `subjects`.`id` WHERE `subjects`.`name` = 'Math' AND `subjects`.`level` = 2 AND (pages.name LIKE '%Division') 
[#<Subject id: 6, name: "Math", position: 1, visible: true, created_at: "2011-12-17 04:25:54", updated_at: "2011-12-17 04:25:54", level: 2>, #<Subject id: 6, name: "Math", position: 1, visible: true, created_at: "2011-12-17 04:25:54", updated_at: "2011-12-17 04:25:54", level: 2>] 
>> 
>> subject.to_sql 
"SELECT `subjects`.* FROM `subjects` WHERE `subjects`.`name` = 'Math' AND `subjects`.`level` = 2" 
>> subject.size 
1 
>> subject.class 
ActiveRecord::Relation 

第一语句:受试者= Subject.where(:名称=> '数学',:级别=> 2) 第二语句:subject.joins(:页)。凡(['页。名称LIKE“, '%司'])

问题:?

  1. 的链接SQL真的返回两行的结果,但subject.size说,只有1?
  2. 我该如何告诉它返回来自页面的列?
  3. 为什么subject.to_sql仍然只显示来自语句1的sql,为什么它没有包含来自语句2的链接的sql?
  4. 本质上,我需要写不同的语句来解析上面列出的sql(或实现相同的结果)?

非常感谢。

回答

4

1)的ActiveRecord会如此,因为您可以根据查询创建关闭Subject类是看你的结果行,并计算出它仅仅是指你查询结果映射到对象不是任意返回的行,为1个唯一的Subject对象,因此只返回那个单个的Subject实例。

2)列数据在那里,但你正在反对ActiveRecord想给你什么,这是对象。如果您希望返回Pages,那么您需要在Page类中创建查询。

3)您没有保存将join(:pages)...添加回subject变量的结果。如果你做了:

subject = subject.joins(:pages).where(['pages.name LIKE ?', '%Division']) 

运行subject.to_sql

4时)要获得页面对象,你可以做这样的事情你会得到完整的查询,通知,我们立足其关闭Page类:

pages = Page.joins(:subject).where(['subjects.name = ? AND subjects.level = ? AND pages.name LIKE ?', 'Math', 2, '%Division']) 

然后从那里访问的主题名称为第一Page对象返回:

pages[0].subject.name 

因为你在第一个连接,将不会导致另一个SQL查询。希望这可以帮助!

+0

辉煌!非常感谢。你回答我所有的问题,现在它工作正常。 :-) – jmsia 2011-12-19 07:09:02