使用Rails update_all方法更新具有另一列值的字段

时间:2012-02-01 08:51:45

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

我正在尝试使用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 个答案:

答案 0 :(得分:12)

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')")

哪会删除替换正则表达式的所有内容。显然,您需要检查数据库的文档,看它是否支持这样的功能。

答案 1 :(得分:0)

虽然接受的答案提供了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}")