其中(Hash)后面是ActiveRecord中的Scoped Where(Hash)

时间:2011-09-16 15:43:01

标签: ruby-on-rails ruby activerecord ruby-on-rails-3.1

简单地说:

class Project
  scope :with_status_1, where(:status => 'test1')
  scope :with_status_2, where('status = ?', 'test2')
end


Project.where(:status => 'test1').where(:status => 'test2')
  Project Load (0.4ms)  SELECT "projects".* FROM "projects" WHERE "projects"."status" = 'test1' AND "projects"."status" = 'test2'

Project.where(:status => 'test').with_status_1
  Project Load (0.5ms)  SELECT "projects".* FROM "projects" WHERE "projects"."status" = 'test1'

Project.where(:status => 'test').with_status_2
  Project Load (0.5ms)  SELECT "projects".* FROM "projects" WHERE "projects"."status" = 'test' AND "projects"."status" = 'test2'

Project.where('status = ?', 'test').with_status_1
  Project Load (0.4ms)  SELECT "projects".* FROM "projects" WHERE "projects"."status" = 'test' AND "projects"."status" = 'test1'

Project.with_status_1.where(:status => 'test')
  Project Load (0.4ms)  SELECT "projects".* FROM "projects" WHERE "projects"."status" = 'test1' AND "projects"."status" = 'test'

Project.with_status_1.where(:status => 'test').with_status_1
  Project Load (0.4ms)  SELECT "projects".* FROM "projects" WHERE "projects"."status" = 'test1'

为什么情况#2和#6会清除前面的条件?

编辑:Rails 3.1

1 个答案:

答案 0 :(得分:0)

where子句将其args发送到build_where

def build_where(opts, other = [])
  case opts
  when String, Array
    [@klass.send(:sanitize_sql, other.empty? ? opts : ([opts] + other))]
  when Hash
    attributes = @klass.send(:expand_hash_conditions_for_aggregates, opts)
    PredicateBuilder.build_from_hash(table.engine, attributes, table)
  else
    [opts]
  end
end

因此,在Hash的情况下,它会重写密钥,因为它会向现有哈希附加新的哈希选项。如果您传递StringArray,则会将其相加。