我在rails控制台中寻找一种方法来查找以特定字符串结尾的任何值,并从值中删除该字符串。
有些事情:
Model.all.each{|x| x.duration.slice!(" weeks")}.where("duration IS NOT NULL")
因此 " 47周" 等值只会变为 " 47" ,但ActiveRecord/ActiveModel
没有“切片方法”,我也不知道相应的方法。
任何想法?
提前致谢...
答案 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
function将duration
字段缩短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