【问题标题】:ActiveRecord pluck to SQLActiveRecord 提取到 SQL
【发布时间】:2023-03-13 22:37:01
【问题描述】:

我知道这两条语句执行相同的 SQL:

使用select

User.select(:email)
# SELECT  `users`.`email` FROM `users`

并使用pluck

User.all.pluck(:email)
# SELECT `users`.`email` FROM `users`

现在我需要获取从每个方法派生的 SQL 语句。鉴于select 方法返回ActiveRecord::Relation,我可以调用to_sql 方法。但是,鉴于结果是一个数组,我无法弄清楚如何获取从对 ActiveRecord::Relation 对象的 pluck 操作派生的 SQL 语句。

请注意,这是对问题的简化。抽取的属性数量可以任意多。

任何帮助将不胜感激。

【问题讨论】:

  • 你想做什么? pluck 使用与 select 相同的 SQL 查询,但它使用 cast_values 返回数组而不是 ActiveRecord::Relation
  • 我正在根据用户输入构建一个查询,我想提供有关实际正在执行的查询的反馈

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


【解决方案1】:

不能to_sqlpluck 链接起来,因为它不会返回 ActiveRecord::relation。如果你尝试这样做,它会抛出这样的异常

NoMethodError: undefined method `to_sql' for [[""]]:Array

我不知道如何获取从 pluck 派生的 SQL 语句 对 ActiveRecord::Relation 对象的操作,给定结果 是一个数组。

嗯,正如 @cschroed 在 cmets 中指出的那样,它们(selectpluck)都执行相同的 SQL 查询。唯一的区别是pluck 返回一个array 而不是ActiveRecord::Relation无所谓您尝试提取多少个属性,SQL 语句将与select 相同

示例:

User.select(:first_name,:email)
#=> SELECT "users"."first_name", "users"."email" FROM "users"

pluck 也一样

User.all.pluck(:first_name,:email)
#=> SELECT "users"."first_name", "users"."email" FROM "users"

所以,你只需要获取select返回的SQL语句,相信pluck也是一样的。就是这样!

【讨论】:

    【解决方案2】:

    您可以对 ActiveRecord::LogSubscriber 类进行猴子修补,并提供一个可以注册任何活动记录查询的单例,即使是那些不返回 ActiveRecord::Relation 对象的查询:

    class QueriesRegister
      include Singleton
      def queries
        @queries ||= []
      end
    
      def flush
        @queries = []
      end
    end
    
    module ActiveRecord
     class LogSubscriber < ActiveSupport::LogSubscriber
    
      def sql(event)
        QueriesRegister.instance.queries << event.payload[:sql]
        "#{event.payload[:name]} (#{event.duration}) #{event.payload[:sql]}"    
      end
     end
    end
    

    运行你的查询:

    User.all.pluck(:email)
    

    然后,检索查询:

    QueriesRegister.instance.queries
    

    【讨论】:

    • queries 数组什么时候清空?
    • 嗯...您需要使用 #flush 方法自行控制
    猜你喜欢
    • 2013-12-10
    • 2015-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多