如何在 Rails 控制台中查找和删除字符串的一部分 - ActiveRecord

How to find and remove part of a string in Rails Console - ActiveRecord

我正在 rails 控制台中寻找一种方法来查找任何以特定字符串结尾的值并将该字符串从值中删除。

大致如下:

Model.all.each{|x| x.duration.slice!(" weeks")}.where("duration IS NOT NULL") 

这样 "47 周" 等值就变成了 "47"。 =27=],但是 ActiveRecord/ActiveModel 没有 Slice 方法,我不知道等效方法。

有什么想法吗??

提前致谢...

您可以使用 where("column_name LIKE <matcher>") 语法搜索具有匹配子字符串的列的模型:

matching_models = Model.where("duration LIKE '% weeks'")

然后迭代结果,使用gsub替换列值

matching_models.find_each do |model|
  model.update_column(:duration, model.duration.gsub(/ weeks$/, "")
end

一些相关要点:

  • 使用find_each而不是each,因为它将分批加载数据以更好地利用内存。

  • gsub用于替换已有的字符串。 / weeks$/ 正则表达式匹配以“weeks”结尾的字符串。

  • 使用
  • model.update_column 而不是 update_attributes 来绕过 ActiveRecord 验证和回调。如果你想 运行 验证和回调,你可以使用 update_attributes

您还可以使用 column_name.to_i 从字符串 47 周

中获取 47

接受的答案工作正常,但如果您有几千条以“周”或更多结尾的记录,速度会明显变慢,因为 Rails 必须从 [=24= 中获取并实例化所有匹配的记录].

一般来说,最好将所有工作交给数据库引擎,如果可能的话,可以这样写:

Model.where("duration LIKE '% weeks'").
      update_all("duration = SUBSTRING(duration, 1, LENGTH(duration) - 6)")
# => UPDATE `models` SET `models`.`duration` = SUBSTRING(duration, 1, LENGTH(duration) - 6) WHERE (duration LIKE '% weeks')

如果您有大量记录要更新,此查询的性能和内存效率会更高。它使用 update_all Rails method to run the UPDATE query on all matching records in the table and the SUBSTRING functionduration 字段缩短 6 个字符,这是 "weeks" 字符串的长度。

正如@BoraMa 所说,接受的答案对于数千条记录来说需要很长时间,并且他们的答案适用于 MySQL 所以这是一个 PostgreSQL 版本:

Model.where("duration LIKE '% weeks'").
      update_all("duration = REPLACE(duration, ' weeks', '')")

而不是 trim 最后 6 个字符,这只是将“weeks”替换为空字符串。你的问题提到 'finish with a particular string' 所以这是锚定到字符串末尾的正则表达式版本:

Model.where("duration LIKE '% weeks'").
      update_all("duration = REGEXP_REPLACE(duration, ' weeks$', '')")