【问题标题】:How to find and remove part of a string in Rails Console - ActiveRecord如何在 Rails 控制台中查找和删除部分字符串 - ActiveRecord
【发布时间】:2016-08-11 04:40:06
【问题描述】:

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

类似的东西:

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

这样 “47 周” 之类的值只会变成 “47”,但没有ActiveRecord/ActiveModel 的 Slice 方法,我不知道等效方法。

有什么想法吗??

提前谢谢...

【问题讨论】:

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


    【解决方案1】:

    您可以使用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$/ 正则表达式匹配以“周”结尾的字符串。

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

    【讨论】:

      【解决方案2】:

      你也可以使用column_name.to_i从字符串47周

      中得到47

      【讨论】:

        【解决方案3】:

        接受的答案可以正常工作,但如果您有几千条以“周”或更多结尾的记录,则会明显变慢,因为 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 个字符,即“周”字符串的长度。

        【讨论】:

          【解决方案4】:

          正如@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$', '')")
          

          【讨论】:

            猜你喜欢
            • 2019-09-28
            • 1970-01-01
            • 1970-01-01
            • 2012-04-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多