Как получить доступ к необработанному оператору SQL, созданному update_all (метод ActiveRecord) - PullRequest
0 голосов
/ 29 августа 2018

Мне просто интересно, есть ли способ получить доступ к необработанному SQL, который выполняется для запроса update_all ActiveRecord. В качестве примера возьмем простой пример ниже:

Something.update_all( ["to_update = ?"], ["id = ?" my_id] )

В консоли rails я вижу необработанный SQL-оператор, поэтому я предполагаю, что он каким-то образом доступен для меня?

PS - я особенно заинтересован в update_all и не могу изменить его на что-либо другое.

Спасибо!

Ответы [ 2 ]

0 голосов
/ 17 июля 2019

Если вы установили RAILS_LOG_LEVEL=debug Rails показывает, какой оператор SQL он выполнил.

# Start Rails console in debug mode
$ RAILS_LOG_LEVEL=debug rails c

# Run your query
[1] pry(main)> Something.update_all( ["to_update = ?"], ["id = ?" my_id] )
SQL (619.8ms) UPDATE "somethings" WHERE id = 123 SET to_update = my_id;

# ^it prints out the query it executed
0 голосов
/ 30 августа 2018

Если вы посмотрите, как update_all реализован , вы не можете вызвать to_sql для него, как для отношений, поскольку он выполняется напрямую и возвращает целое число (количество выполненных строк) .

Нет способа подключиться к потоку или получить желаемый результат, кроме как путем дублирования всего метода и изменения последней строки:

module ActiveRecord
  # = Active Record \Relation
  class Relation
    def update_all_to_sql(updates)
      raise ArgumentError, "Empty list of attributes to change" if updates.blank?

      if eager_loading?
        relation = apply_join_dependency
        return relation.update_all(updates)
      end

      stmt = Arel::UpdateManager.new

      stmt.set Arel.sql(@klass.sanitize_sql_for_assignment(updates))
      stmt.table(table)

      if has_join_values? || offset_value
        @klass.connection.join_to_update(stmt, arel, arel_attribute(primary_key))
      else
        stmt.key = arel_attribute(primary_key)
        stmt.take(arel.limit)
        stmt.order(*arel.orders)
        stmt.wheres = arel.constraints
      end

      #- @klass.connection.update stmt, "#{@klass} Update All"
      stmt.to_sql
    end
  end
end

Причина, по которой вы видите операторы журнала, заключается в том, что они регистрируются соединением, когда оно выполняет операторы. Хотя вы можете переопределить ведение журнала, на самом деле это невозможно сделать для вызовов из одного метода AR.

...