0

我有一个非常复杂的查询(它找到两个城镇之间的公共汽车连接)并且我不知道如何从连接中访问数据(我想知道连接从哪个站点开始以及在哪个站点开始结尾)。是否可以使用 ActiveRecord 访问这些数据?

Course.joins("INNER JOIN stop_times as start_stop ON start_stop.course_id=courses.id")
.joins("INNER JOIN stop_times as end_stop ON end_stop.course_id = courses.id")
.joins('INNER JOIN stops as start_stopi ON start_stop.stop_id = start_stopi.id')
.joins('INNER JOIN stops as end_stopi ON end_stop.stop_id = end_stopi.id')
.where('start_stop.hour>= ? OR (start_stop.hour>= ? AND start_stop.minute>= ?)',hour,(hour+1)%24,minute)
.where('start_stopi.town_id = ? and end_stopi.town_id = ?',start_town,end_town)
.where('start_stop."order"<end_stop."order"').order('start_stop.minute ASC').order('start_stop.hour ASC')

编辑:我已经设法重写它以使用活动记录连接,虽然它破坏了我的名字,但它有效。

Course.joins(end_stop_times: :stop).joins(start_stop_times: :stop)
.where('start_stop_times_courses.hour>= ? OR (start_stop_times_courses.hour>= ? AND start_stop_times_courses.minute>= ?)',hour,(hour+1)%24,minute)
.where('stops_stop_times.town_id = ? and stops.town_id = ?',start_town,end_town)
.where('start_stop_times_courses."order"<stop_times."order"')
.order('start_stop_times_courses.minute ASC').order('start_stop_times_courses.hour ASC')

使用这个新的查询模型是:

class Course < ActiveRecord::Base
  belongs_to :carrier
  has_many :end_stop_times, class_name: 'StopTime'
  has_many :start_stop_times, class_name: 'StopTime'

class Stop < ActiveRecord::Base
  belongs_to :town

class StopTime < ActiveRecord::Base
  belongs_to :stop
  belongs_to :course
4

3 回答 3

0

您需要添加以下内容:

your_query.select('courses.*, start_stopi.id as start_stop_id, end_stopi.id as end_stop_id)

然后您可以通过在课程对象上调用 start_stop_id 和 end_stop_id 来访问它。

但是,您可能应该对此类操作使用关联。你能给我们展示你的模型吗?

于 2013-09-16T16:07:08.670 回答
0

检查您的日志以获取此查询的输出,您应该发现它以select courses.*- 开头,因此它不会带来包含表中的数据。

您可以在查询中添加一些select other_table.some_column语句,但这不是 rails 方式。

我建议您将范围分成相关模型 - 将范围放入stop_times模型(和其他模型)中,以便您可以在实际想要从中获取数据的对象上调用范围。

于 2013-09-16T16:13:30.803 回答
0

当您构建具有这种复杂性的自定义 SQL 时,我认为您采用 Rails 的方式做事太过分了。您实际上没有使用 activerecord 关联信息来构建它,并且您构建了一个非常丑陋且难以阅读的编程结构。

我建议你重写它以及格式化 SQL

results  = ActiveRecord::Base.connection.execute(
"select c.*
 from   courses    c
 join   stop_times ss on ss.course_id = c.id
 join   stop_times es on es.course_id = c.id
 ... etc ...
 where  (start_stop.hour  >= #{ActiveRecord::Base.sanitize(hour)} or
        ... etc ...")

现在,您可以将模型和关联改进到不需要这种复杂程度的程度(例如,课程之间的关联,stop_times(开始)和 stop_times(结束)可能很好地封装在 activerecord 中,但是目前,您似乎以一种非常不舒服的方式陷入了纯 SQL 和纯 activerecord 方法之间。

于 2013-09-16T16:29:06.670 回答