Rails 这算特性还是算 Bug?

hjleochen · July 10, 2015 · Last by zhang_soledad replied at July 12, 2015 · 1997 hits
class User < ActiveRecord::Base

  def self.test_by_conditions(id)
    User.where(id:id).to_sql
    #......
  end

  def self.test_by_id(id)
    User.find(id).to_sql
    #......
  end

end
User.where(id:1).to_sql
#SELECT "users".* FROM "users" WHERE "users"."id" = 1

User.where(id:1).test_by_conditions(2)
#SELECT "users".* FROM "users" WHERE "users"."id" = 1 AND "users"."id" = 2

User.where(id:1).test_by_id(2)
#User Load (0.3ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? AND "users"."id" = ? LIMIT 1  [["id", 1], ["id", 2]]
#ActiveRecord::RecordNotFound: Couldn't find User with 'id'=2 [WHERE "users"."id" = ?]

应该是 Arel 继承了前面的条件,似乎是到同一个 arel.scrope 里面去了,应该算是个 Bug 吧。

为什么要这么写…… User.where() 返回的是 Relation 吧……?

首先不要在 method 里面再写 User 了,这样比较丑,直接 where, find 就可以了。

第三个测试找不到记录,完全符合预期。你的命令是要在 id 为 1 的数据里面找到 id 为 2 的记录,当然找不到。

多个串接命令下的 SQL 合并成一个是 feature, 而且是必须的。要是一个个分开,那就费事了 :)

#1 楼 @msg7086 #2 楼 @billy

上面的代码只是为了方便说明举例写的,方法里面还有 #...... 表示更多逻辑哦。

实际代码中当然不是有意要这么写,但是 在 class methods(scope)里面调用的关于当前 model 的方法 (Relation) 中均会包含 scope 之前的 where 条件。

当然是特性了!

如果不需要的之前的 scope 的话,要使用 User.unscoped

照你的思路 自动覆盖掉前面的 scope 还能用?

You need to Sign in before reply, if you don't have an account, please Sign up first.