【问题标题】:Rails 4 ActiveRecord includes(:model) without its default_scopeRails 4 ActiveRecord 包括(:model) 没有它的 default_scope
【发布时间】:2013-10-10 08:50:16
【问题描述】:

我的 Rails 应用程序出现以下情况。有两种模型,比如说用户和公司:

class User < ActiveRecord::Base
  belongs_to :company
  default_scope -> {where(removed_at: nil)}
end

class Company < ActiveRecord::Base
  has_many :users
end

我现在想要的是加载公司记录并包含用户

Company.unscoped.all.includes(:users)

什么会导致对包含默认范围的用户表的查询。 所以我得到了预取所有未删除用户的公司记录。但在这种情况下,我也想要 remove_at 不为空的用户(=> 删除的用户记录)。 “unscoped”方法仅适用于 Company 模型,不适用于 User 模型。

有没有办法做到这一点?感谢您的任何想法!

【问题讨论】:

    标签: ruby-on-rails activerecord


    【解决方案1】:

    此方法接受一个块。块内的所有查询都不会使用 default_scope:

    User.unscoped { Company.includes(:users).all }
    

    或:

    User.unscoped do
     Company.includes(:users).all
    end
    

    【讨论】:

    • 不,不幸的是,这并不能避免调用 default_scope (Rails 4)。
    • 尝试将all 删除到最后。
    • 这两个版本都不适合我,无论有没有(已弃用)all。
    • 在 Rails 3 中它确实有效。 stackoverflow.com/a/14446317。也许 Rails 4 有问题
    • 您必须使用all 才能在块中执行查询。我的意思是你应该把它传递到最后。
    【解决方案2】:

    关系不保留此状态,稍后访问它时(Rails 6.0)

    在某些情况下,一种可能的解决方法是强制解决,例如:

    User.unscoped { Company.includes(:users).to_a }
    

    to_a 在块中解析关系,因此有效地删除了范围。

    【讨论】:

      【解决方案3】:

      这是我在 Rails 4.0 应用程序中使用的解决方案

      class User < ActiveRecord::Base
        belongs_to :company
        default_scope -> {where(removed_at: nil)}
      end
      
      class UserUnscoped < User
        self.default_scopes = []
      end
      
      class Company < ActiveRecord::Base
        has_many :users, class_name: "UserUnscoped"
      end
      
      Company.unscoped.all.includes(:users)
      

      【讨论】:

        【解决方案4】:

        我有一个非常分支的 STI 模型集。因此,对我有用的唯一方法(Rails 4.2.5)如下:

        class UndeadUser < ActiveRecord::Base
          self.table_name = 'users'
        end
        
        class User < UndeadUser
          # real logic here
        end
        
        class Employee < User; end
        class Manager < Employee; end
        
        # grouping model
        class Organization < ActiveRecord::Base
          has_many :employees
        
          has_many :users, class: UndeadUsers
          before_destroy :really_destroy_users_and_data! # in case of using acts_as_paranoid or paranoia gems it might be helpful
        end
        

        @abstractcoder 的解决方案对我不起作用,因为当 UndeadUser 从 User 继承时,rails 会尝试添加 WHERE users.type IN ('UndeadUser')

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-05-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-04-08
          相关资源
          最近更新 更多