Rails ActiveRecord这样的链式接口是如何建立的?

问题描述 投票:3回答:1

我很好奇。怎樣 User.where(name: 'Foo').where(age: 20) 只用一次数据库调用就能工作?

该方法是否能在 where 知道它是否是链条的最后一个,并改变其行为?如果是,如何才能做到这一点?

ruby-on-rails ruby rails-activerecord
1个回答
5
投票

它返回 self 每次将查询添加到它的内部查询构建器后。

where 并不一定知道它在哪里,ActiveRecord在查询数据库之前就会等待自己被枚举。例如

users = User.where(active: true)
users.loaded? # false 
users.each { }
users.loaded? # true 

each, map, first, last、等都会触发查询加载。

下面是一个超牛的查询建立器的例子。

class FakeRecord
  include Enumerable
  def self.all_args
    @all_args ||= []
  end

  def self.where(*args)
    all_args << args 
    self
  end

  def self.each
    puts "Executing sql #{all_args.join(", ")}"
    yield [1, 2, 3]
  end
end

FakeRecord.where(potato: true).where(dinosaur: false).each do |thing|
  puts thing
end
© www.soinside.com 2019 - 2024. All rights reserved.