Использование метода Rails update_all для обновления полей со значением из другого столбца - PullRequest
6 голосов
/ 01 февраля 2012

Я пытаюсь обновить поле с помощью update_all.Однако мне нужно, чтобы значение было взято из другого поля, которое переписано в мой конкретный формат.

Если у меня есть что-то подобное в моей модели:

 def self.clean_mac_address()
   clean_mac_address = :macaddress.gsub(/[^0-9a-z]/i, '')
 end

Когда я запускаю это:

 Radacct.update_all("mac_clean = #{clean_mac_address}")

Я получаю сообщение об ошибке:

 NoMethodError: undefined method `gsub' for :macaddress:Symbol

Есть мысли, как мне это сделать?Или есть более простой способ обновить поле?

Ответы [ 2 ]

12 голосов
/ 01 февраля 2012

update_all генерирует один SQL-запрос для запуска - он не может делать такие умные вещи, как преобразование произвольных битов ruby ​​в эквивалентный SQL.

Вам нужно либо загрузить все свои экземпляры (например, через find_each) и исправить их один за другим (т.е. не использовать update_all), например,

Foo.find_each do |foo|
  # update foo here
  foo.save!
end      

Или найтиспособ выразить эту операцию очистки в SQL.Например, Postgres имеет функцию regexp_replace

Foo.update_all("some_column = regexp_replace(some_column, 'your_regexp_here', '','g')")

, которая удаляет все, что заменяет это регулярное выражение.Очевидно, вам нужно проверить документацию для вашей базы данных, чтобы увидеть, поддерживает ли она такую ​​функцию.

0 голосов
/ 12 февраля 2018

В то время как принятый ответ обеспечивает хороший способ update_all, я бы использовал

read_with_clean_addr = Radacct.where(mac_clean: :macaddress.gsub(/[^0-9a-z]/i, ''))
read_with_clean_add.update_all(mac_clean: "#{clean_mac_address}")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...