jms*_*sia 2 join active-relation ruby-on-rails-3
我有两个处于一对多关系的表(主题和页面)。我想从主题和页面添加标准来解析 sql,但进度非常缓慢,并且经常遇到问题。我是 Rails 的新手,请帮忙。
class Subject < ActiveRecord::Base
has_many :pages
end
class Page < ActiveRecord::Base
belongs_to :subject
end
Run Code Online (Sandbox Code Playgroud)
主题中的样本数据,在下面列出了三列:
id name level
1 'Math' 1
6 'Math' 2
...
Run Code Online (Sandbox Code Playgroud)
页中的示例数据,下面列出了列:
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
Run Code Online (Sandbox Code Playgroud)
鉴于我不知道subject.id,我只知道主题名称和级别以及页面名称。这是我想要生成的 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' ;
Run Code Online (Sandbox Code Playgroud)
我希望在结果中得到两行:
subjects.id subjects.name pages.id pages.name
----------- ------------- -------- -----------
6 Math 6 Simple Division
6 Math 8 Hard Division
Run Code Online (Sandbox Code Playgroud)
这是一个非常简单的 sql,但我一直无法在 Rails 中获得想要的东西。
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
Run Code Online (Sandbox Code Playgroud)
第一条语句:subject = Subject.where(:name => 'Math', :level => 2) 第二条语句:subject.joins(:pages).where(['pages.name LIKE ?', '%Division'] )
问题:
非常感谢。
1) ActiveRecord 会将您的查询结果映射到对象而不是任意返回的行,因此因为您基于Subject类创建查询,它正在查看您的结果行并发现它只引用 1 个唯一Subject对象,因此返回只是那个单一的Subject实例。
2) 列数据在那里,但是您正在反对 ActiveRecord 想要给您的内容,即对象。如果您希望返回 Pages,那么您需要基于Page类创建查询。
3)您没有保存将join(:pages)...返回添加到subject变量中的结果。如果你这样做:
subject = subject.joins(:pages).where(['pages.name LIKE ?', '%Division'])
Run Code Online (Sandbox Code Playgroud)
运行时你会得到完整的查询 subject.to_sql
4) 要获取页面对象,您可以执行以下操作,请注意我们将其建立在Page类的基础上:
pages = Page.joins(:subject).where(['subjects.name = ? AND subjects.level = ? AND pages.name LIKE ?', 'Math', 2, '%Division'])
Run Code Online (Sandbox Code Playgroud)
然后从那里访问Page返回的第一个对象的主题名称:
pages[0].subject.name
Run Code Online (Sandbox Code Playgroud)
因为您在第一个中有连接,所以不会导致另一个 SQL 查询。希望这可以帮助!
| 归档时间: |
|
| 查看次数: |
17149 次 |
| 最近记录: |