耙子/导轨.保存!不更新数据库 [英] rake / rails .save! not updating database
问题描述
我正在尝试通过 rake 任务保存对我的数据库的更改.
I am trying to save changes to my database trough a rake task.
在我的 rake 任务中,我执行以下操作:
In my rake task I do something like:
namespace :parts do
desc "Update Parts table, swap names in title"
task :swap => :environment do
Part.swap
end
end
在我的 Part 课上
In my Part class I do
def self.swap
Part.all.each do |part|
if (part.title =~ REGEX) == 0
part.title.gsub! REGEX, '\2 \1'
puts part.title
part.save!
end
end
end
然而,这并不能保存零件.save!
确实返回 true.puts part.title
确实返回了我想要的值.
However, this does not save the part. The save!
does return true. the puts part.title
does return the value I want.
如果我打电话
Part.update(part.id, title: part.title)
数据库正确更新.为什么是这样?我在循环中做错了什么吗?我正在使用 Rails 3.1.3、Rake 0.9.2.2 和 MySQL2 0.3.7
The database updates properly. Why is this? Am I doing something wrong in my loop? I am working with Rails 3.1.3, Rake 0.9.2.2 and MySQL2 0.3.7
推荐答案
这是因为 ActiveRecord 检测属性更改的方式是通过 setter.因此,如果您在属性上使用 gsub!
,ActiveRecord 不知道它需要更新数据库.
It's because the way ActiveRecord detects that attributes are changed is through the setter. Therefore, if you use gsub!
on an attribute, ActiveRecord doesn't know it needs to update the database.
您可能必须这样做:
part.title = part.title.gsub REGEX, '\2 \1'
评论更新
此外,如果您尝试将标题分配给另一个变量,然后 gsub!它也不会工作,因为它是同一个对象(来自我的项目的代码,变量名称不同).
Update from comment
Also, if you try to assign title to another variable and then gsub! it won't work either because it's the same object (code from my project, variable names different).
ruby-1.9.3-p0 :020 > t = p.name
=> "test"
ruby-1.9.3-p0 :023 > t.object_id
=> 70197586207500
ruby-1.9.3-p0 :024 > p.name.object_id
=> 70197586207500
ruby-1.9.3-p0 :025 > t.gsub! /test/, 'not a test'
=> "not a test"
ruby-1.9.3-p0 :037 > p.name = t
=> "not a test"
ruby-1.9.3-p0 :026 > p.save
(37.9ms) BEGIN
** NO CHANGES HERE **
(23.9ms) COMMIT
=> true
您必须在修改字符串之前.dup
.
You have to .dup
the string before modifying it.
ruby-1.9.3-p0 :043 > t = p.name.dup
=> "test"
ruby-1.9.3-p0 :044 > t.gsub! /test/, 'not a test'
=> "not a test"
ruby-1.9.3-p0 :045 > p.name = t
=> "not a test"
ruby-1.9.3-p0 :046 > p.save
(21.5ms) BEGIN
(20.8ms) UPDATE "projects" SET "name" = 'not a test', "updated_at" = '2012-01-02 07:17:22.892032' WHERE "projects"."id" = 108
(21.5ms) COMMIT
=> true
这篇关于耙子/导轨.保存!不更新数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!