【问题标题】:How to override default_scope in client_side_validations gem?如何覆盖 client_side_validations gem 中的 default_scope?
【发布时间】:2015-02-14 08:05:26
【问题描述】:

我的大多数模型上都有default_scope,范围为current_user.company。我在我的注册页面上使用了 client_side_validations gem,这意味着没有租户集。

当唯一性验证器在 @user.email 上运行时,default_scope 会阻止验证正常运行(因为 company_id 为零),因此看起来总是一个唯一的结果。

我的用户模型:

# 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 最实用的方法是什么?

【问题讨论】:

    标签: ruby-on-rails validation devise client-side-validation default-scope


    【解决方案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
    

    您可以像上面看到的那样将默认范围定义为类方法。

    见文档:http://apidock.com/rails/ActiveRecord/Base/default_scope/class

    【讨论】:

    • 感谢您的意见,但这个问题更多的是关于 client_side_validations gem 而不是 default_scope 的优缺点。我最终花钱修补了我的应用程序中的 gem 以提供所需的行为。
    【解决方案2】:

    我不认为覆盖 default_scope 是个好主意。

    您应该将逻辑移至控制器。不知道你用的是不是权威。它将提供一个作用域函数。

    如果没有,请尝试将此范围移动到控制器。

    def current_users
       @users||= User.where(company_id: Company.current_id)
    end
    

    【讨论】:

    • 感谢您的意见,但这个问题更多的是关于 client_side_validations gem 而不是 default_scope 的优缺点。我最终花钱修补了我的应用程序中的 gem 以提供所需的行为。
    【解决方案3】:

    我最终花钱修补了我的应用程序中的 gem 来解决我的问题。我还会将更改提交给 gem 作者,因为我不确定这是一个错误还是他们最初想要的行为。

    # 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?
    

    【讨论】:

      猜你喜欢
      • 2010-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多