在导轨中订购结果3 ..它的工作方式就像魔术一样,但为什么呢?

时间:2011-03-08 15:17:34

标签: ruby-on-rails ruby-on-rails-3

class Course < ActiveRecord::Base
  belongs_to :course_category
  belongs_to :client
  belongs_to :user_created, :foreign_key => :user_created_by, :class_name => "User"
  belongs_to :user_updated, :foreign_key => :user_last_updated_by, :class_name => "User"
  has_many :course_steps, :dependent => :destroy
  has_many :steps, :through => :course_steps
  has_many :course_requests
end

这是rails控制台的输出......

>> c=Course.first
=> #<Course id: 1, course_category_id: 1, client_id: 1, user_created_by: 1, user_last_updated_by: 1, title: "Test Course 1", summary: "", hidden: false, auto_register: false, created_at: "2011-03-08 01:03:47", updated_at: "2011-03-08 01:03:47">
>> c.course_steps
=> [#<CourseStep id: 3, step_id: 2, course_id: 1, position: nil, created_at: "2011-03-08 15:03:44", updated_at: "2011-03-08 15:03:44">, #<CourseStep id: 4, step_id: 3, course_id: 1, position: nil, created_at: "2011-03-08 15:03:46", updated_at: "2011-03-08 15:03:46">]
>> c.course_steps.order("id DESC")
=> [#<CourseStep id: 4, step_id: 3, course_id: 1, position: nil, created_at: "2011-03-08 15:03:46", updated_at: "2011-03-08 15:03:46">, #<CourseStep id: 3, step_id: 2, course_id: 1, position: nil, created_at: "2011-03-08 15:03:44", updated_at: "2011-03-08 15:03:44">]
>> c.course_steps.order("id DESC").to_sql
=> "SELECT \"course_steps\".* FROM \"course_steps\" WHERE (\"course_steps\".course_id = 1) ORDER BY id DESC"
>> c.course_steps.order("position DESC").to_sql
=> "SELECT \"course_steps\".* FROM \"course_steps\" WHERE (\"course_steps\".course_id = 1) ORDER BY position DESC"
>> c.steps.order("position DESC").to_sql
=> "SELECT \"steps\".* FROM \"steps\" INNER JOIN \"course_steps\" ON \"steps\".id = \"course_steps\".step_id WHERE ((\"course_steps\".course_id = 1)) ORDER BY position DESC"
>> c.steps.class
    => Array
    >> c.course_steps.class
    => Array
    >> 

我感到困惑的部分是:(我很高兴他们的工作,但我只是想知道为什么)

  1. 我可以在course_steps上调用“order”(这是一个数组)c.course_steps.order(“id DESC”)!?!?

  2. 当位置甚至不是步骤表的一部分时,我可以调用c.steps.order(“position DESC”)。它以某种方式进行了神奇的连接。

1 个答案:

答案 0 :(得分:1)

  

我可以打电话给“订单”   course_steps(这是一个数组)   c.course_steps.order(“id DESC”)!?!?

正如我所看到的,rails在每个链接方法之后不会立即查询数据库。相反,它处理整个链并构造查询。 因此order数组不会调用course_steps。它只是附加查询的order部分。

这是来自Beginning Rails的qoute:

  

请注意,当您致电订单时   方法,它返回一个数组对象作为   你可能已经预料到了。有一件事   发生在背景上的是   Active Record允许您链接   之前调用多个方法   将命令发送到数据库;   所以你可以打电话给所有,然后   订单,以及其他一些方法我们会   在下一章谈到   创建更精确的数据库查询。   此外,Active Record足够聪明   使用延迟加载,这是一种做法   只有在点击数据库时   必要的 - 在这个例子中,当你   打电话给每个方法。