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

Ruby on rails 如何在Rails控制台-ActiveRecord中查找和删除字符串的一部分,ruby-on-rails,activerecord,activemodel,rails-console,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没有切片方法,我也不知道等效值 有什么想法吗 提前感谢…您可以使用where(“column\u name LIKE”)语法搜索具有匹配子字符

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

大致如下:

Model.all.each{|x| x.duration.slice!(" weeks")}.where("duration IS NOT NULL") 
因此,像“47周”这样的值就变成了“47”,但是
ActiveRecord/ActiveModel
没有切片方法,我也不知道等效值

有什么想法吗

提前感谢…

您可以使用
where(“column\u name LIKE”)
语法搜索具有匹配子字符串的列的模型:

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\u列
    而不是
    update\u属性
    来绕过
    ActiveRecord
    验证和回调。如果要运行验证和回调,可以使用
    update\u attributes


您也可以使用
列名。to\u i
从字符串47周获得47接受的答案工作正常,但如果您有几千条以“周”或更多结尾的记录,那么速度会明显变慢,因为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')

如果您有大量记录要更新,则此查询的性能和内存效率将大大提高。它使用对表中所有匹配记录运行更新查询,并将
持续时间
字段缩短6个字符,这是“weeks”字符串的长度。

正如@BoraMa所说,接受的答案将花费数千条记录的很长时间,它们的答案适用于MySQL,因此这里是PostgreSQL版本:

Model.where("duration LIKE '% weeks'").
      update_all("duration = REPLACE(duration, ' weeks', '')")
与其删减最后6个字符,不如用空字符串替换“weeks”。您的问题提到“使用特定字符串完成”,因此这里是固定在字符串末尾的正则表达式版本:

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