我的大多数模型都有default_scope
current_user.company
范围。我在注册页面上使用了client_side_validations gem,这意味着没有租户设置。
当唯一性验证程序在@user.email
上运行时,default_scope会阻止验证正常运行(因为company_id
为nil),因此看起来总是看起来是唯一的结果。
我的用户模型:
# user.rb
...
default_scope { where(company_id: Company.current_id) }
...
验证电子邮件时运行此查询:
Started GET "/validators/uniqueness?case_sensitive=true& \
user%5Bemail%5D=me%2B40%40example.com&_=1423897339854" \
for 76.175.168.2 at 2015-02-14 07:02:30 +0000
User Exists (0.4ms) SELECT 1 AS one FROM "users" WHERE \
"users"."company_id" IS NULL AND "users"."email" = 'me@example.com' LIMIT 1
当我从用户模型中删除default_scope
时,我得到了正确的结果和正确的验证:
Started GET "/validators/uniqueness?case_sensitive=true& \
user%5Bemail%5D=me%2B40%40example.com&_=1423897339854" \
for 76.175.168.2 at 2015-02-14 07:02:30 +0000
User Exists (0.4ms) SELECT 1 AS one FROM "users" WHERE \
"users"."email" = 'me@example.com' LIMIT 1
当这个gem运行电子邮件验证程序时,覆盖default_scope
的最实用的方法是什么?
答案 0 :(得分:1)
通常我会说:不要使用default_scope,因为你会遇到各种各样的问题。在我看来,默认范围可以订购。
但是你可以这样解决它:
class User < ActiveRecord::Base
def self.default_scope
#i don't know what company represents here
where(company_id: Company.current_id) if Company.present?
end
end
您可以将默认范围定义为类方法,如上所示。
请参阅doc:http://apidock.com/rails/ActiveRecord/Base/default_scope/class
答案 1 :(得分:0)
我认为覆盖default_scope不是一个好主意。
您应该将逻辑移动到控制器。我不知道你是否正在使用专家。它将提供范围功能。
如果没有,请尝试将此范围移至控制器。
def current_users
@users||= User.where(company_id: Company.current_id)
end
答案 2 :(得分:0)
我最终在我的应用程序中修补了宝石修补我的问题。我还将更改提交给宝石作者,因为我不确定这是一个错误还是他们原来想要的行为。
# lib/client_side_validations/active_record/middleware.rb
def self.is_unique?(klass, attribute, value, params)
...
!klass.where(relation).exists?
end
# patched the above line to: !klass.unscoped.where(relation).exists?