Ruby on rails 耙子/轨道。保存!不更新数据库
我试图通过rake任务保存对数据库的更改 在我的rake任务中,我会执行以下操作:Ruby on rails 耙子/轨道。保存!不更新数据库,ruby-on-rails,rake,Ruby On Rails,Rake,我试图通过rake任务保存对数据库的更改 在我的rake任务中,我会执行以下操作: namespace :parts do desc "Update Parts table, swap names in title" task :swap => :environment do Part.swap end end 在我的班里,我喜欢 def self.swap Part.all.each do |part| if (part.title =~ REGEX)
namespace :parts do
desc "Update Parts table, swap names in title"
task :swap => :environment do
Part.swap
end
end
在我的班里,我喜欢
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
但是,这不会保存零件。保存代码>返回true。放置part.title
确实返回了我想要的值
如果我打电话
Part.update(part.id, title: part.title)
数据库正确更新。为什么会这样?我在循环中做错了什么吗?
我正在使用Rails 3.1.3、Rake 0.9.2.2和MySQL2 0.3.7,这是因为ActiveRecord检测属性更改的方式是通过setter实现的。因此,如果您使用gsub代码>在属性上,ActiveRecord不知道它需要更新数据库
您可能必须这样做:
part.title = part.title.gsub REGEX, '\2 \1'
根据评论更新
另外,如果您尝试将title分配给另一个变量,然后是gsub!它也不会工作,因为它是同一个对象(来自项目的代码,变量名不同)
在修改字符串之前,必须.dup
该字符串
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
我试过做text.gsub对一个变量进行编码>然后设置part.title=text
,但这不起作用。如果这样做,则必须先对变量进行.dup
操作。您可能需要将part.title=~REGEX
测试移到数据库中,做Model.all.each
通常都是一个坏主意。你所说的:将其移动到数据库中是什么意思?我想用一个字段来更新每个记录,该字段与我在该条件下的regex criteriaQuery(Part.where(…)
)相匹配,并让数据库处理该部分,将整个表拉入Ruby land并测试那里的记录。而且,根据数据库的不同,您可以在数据库中完成整个替换,而无需将任何数据拉入Ruby。这取决于您使用的datZbase和正则表达式的外观。
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