【发布时间】:2011-04-25 22:26:23
【问题描述】:
我拼命想理解 Arel,主要是因为我讨厌处理 SQL;我做得很好,但我碰壁了。
我一直在使用 Rails 3.0.0,我正在尝试使用一些数学进行复杂的查询。实际情况要复杂得多,但我已经简化了一点。在我的示例中,我有一个包含特定字符串字段的表,并且我想要所有记录的计数,以及该字段的两个可能值中的每一个的计数,按外部 id 分组。
在 Rails 3.0.0 下,我可以这样做(控制台命令):
t = Arel::Table.new(:some_thingies)
e = t .project(t[:foreign_id], t[:foreign_id].count.as('all_count')) .group(t[:foreign_id])
c = t.where(t[:some_field].eq('type1')).project(t[:foreign_id], t[:foreign_id].count.as('type1_count')).group(t[:foreign_id])
x = e
x = x.join(c).on(e[:foreign_id].eq(c[:foreign_id]))
此时我可以执行 x.to_sql 和...好吧,我不完全确定它是否正确,但结果看起来正确,除了两次使用 foreign_id 列。
SELECT
`some_thingies_external`.`foreign_id`,
`some_thingies_external`.`all_count`,
`some_thingies_external_2`.`foreign_id`,
`some_thingies_external_2`.`type1_count`
FROM
(SELECT
`some_thingies`.`foreign_id`, COUNT(`some_thingies`.`foreign_id`)
AS `type1+count`
FROM `some_thingies`
GROUP BY `some_thingies`.`foreign_id`) `some_thingies_external`
INNER JOIN
(SELECT `some_thingies`.`foreign_id`, COUNT(`some_thingies`.`foreign_id`)
AS `type1_count`
FROM `some_thingies`
WHERE `some_thingies`.`type` = 'type1'
GROUP BY `some_thingies`.`foreign_id`) `some_thingies_external_2`
ON `some_thingies_external`.`foreign_id` = `some_thingies_external_2`.`foreign_id`
到目前为止一切顺利。但是,当我尝试像这样加入第二组计数时:
i = t.where(t[:some_field].eq('type2')).project(t[:foreign_id], t[:foreign_id].count.as('type2_count')).group(t[:foreign_id])
x = x.join(i).on(e[:foreign_id].eq(i[:foreign_id]))
它只是挂断了,让我以为我在打this bug
(顺便说一句,我要添加更多计数,理想情况下,'some_thingies' 本身应该是一个 arel 对象,表示对我们正在计数的事物进行更多过滤......但我离题了......)
所以,我决定尝试最新的 edge Arel 和 Rails,并相应地提升了我的宝石:
gem 'rails', :git => 'git://github.com/rails/rails.git'
gem 'rack', :git => 'git://github.com/rack/rack.git'
gem 'arel', :git => 'http://github.com/brynary/arel.git'
现在当我尝试进行 first 加入时,它惨遭失败:
ruby-1.9.2-preview3 > x = x.join(c).on(e[:foreign_id].eq(c[:foreign_id]))
NoMethodError: undefined method `[]' for #<Arel::SelectManager:0x00000104311e38>
from (irb):12
from /Users/stephan/.rvm/gems/ruby-1.9.2-preview3/bundler/gems/rails-c42ea2172eb9/railties/lib/rails/commands/console.rb:44:in `start'
from /Users/stephan/.rvm/gems/ruby-1.9.2-preview3/bundler/gems/rails-c42ea2172eb9/railties/lib/rails/commands/console.rb:8:in `start'
from /Users/stephan/.rvm/gems/ruby-1.9.2-preview3/bundler/gems/rails-c42ea2172eb9/railties/lib/rails/commands.rb:33:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'
这似乎不是 Arel 中的错误 - 如果有的话,它似乎更像是它之前工作的事实是错误。我想我只是不知道 Arel::SelectManager 是什么以及如何处理它。看起来我做得很好,但我真的不明白发生了什么。
我是否需要根据我拥有的 SelectManager 以某种方式创建一个新表?或者在我的配置中做错了什么导致 [] 语法失败?还是我完全不明白 Arel 做了什么?我仍然不太明白我应该对 Arel::Rows 做什么,但我想我会掌握的;我怀疑我可以用 project() 去掉结果中多余的外键...
但我还是很迷茫。哈哈!
附言'railties' 是否与 'frailties' 或 'mail guy' 押韵?
【问题讨论】:
标签: sql ruby-on-rails-3 arel