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

时间:2016-04-19 07:09:20

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

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

有些事情:

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

因此 " 47周" 等值只会变为 " 47" ,但ActiveRecord/ActiveModel没有“切片方法”,我也不知道相应的方法。

任何想法?

提前致谢...

4 个答案:

答案 0 :(得分:3)

您可以使用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$/正则表达式匹配以&#34结尾的字符串;周&#34 ;.

  • 使用
  • model.update_column代替update_attributes来绕过ActiveRecord验证和回调。如果要运行验证和回调,可以使用update_attributes

答案 1 :(得分:2)

接受的答案是正确的,但如果你有几千条记录以&#34;结尾,则会明显变慢。周&#34;或更多,因为Rails必须从表中获取并实例化所有匹配的记录。

一般情况下,如果可能的话,最好将所有工作留给数据库引擎,这可以这样写:

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对表中的所有匹配记录运行UPDATE查询,并使用SUBSTRING functionduration字段缩短6个字符,这是&#34;的长度。周&#34;字符串。

答案 2 :(得分:1)

正如@BoraMa 所说,接受的答案需要很长时间才能获得数千条记录,而且他们的答案适用于 MySQL,所以这是 PostgreSQL 版本:

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

不是修剪最后 6 个字符,而是将“周”替换为空字符串。您的问题提到“以特定字符串结束”,因此这是锚定到字符串末尾的正则表达式版本:

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

答案 3 :(得分:0)

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