我有一个简单的rails webservice,它公开了一个允许客户端发布新记录的JSON API。处理POST时,它首先创建引用的记录,但同时也更新一些相关的记录。
@foo = Foo.new(foo_params)
if @foo.save
related_list = Foo.where(:some_id => foo_params[:list])
related_list.each do |related|
# <figure out some stuff here>
related.update_attributes(stuff)
end
# debug spew
@test = Foo.find(a_related_record_id)
puts @test.as_json
format.json { render json: @foo.as_json }
end
我认识到这是一个糟糕的两阶段提交模式,它滥用典型的REST模型,但我继承了这段代码。我最终要解决它;这是分阶段“修复”计划的一部分。
此代码在本地测试框中完美运行。当部署到Heroku时,我输入调试spew,显示调用update_attributes后模型显然正在更新。但是,不知何故,该模型实际上并未更新。当我之后使用网页检查“相关”记录时,没有更新任何“东西”更改。由于调试spew似乎显示正在更新的记录,我对此感到非常困惑。任何见解?
更新
我回过头调试时发现的一件事是,即使记录中的字段显示,updated_at日期时间也不会改变。您可以从下面的行中看到,呼叫是在UTC时间8:04:15左右进行的。另外,我验证update_attributes返回true,因此我没有错误。
在调用update_attributes之前:
←[36m2012-09-20T08:04:15 + 00:00 app [web.1]:←[0m {“created_at”=&gt; Thu,2012年9月20日00:43:45 UTC +00:00 ,“somefield”=&gt;“”,“id”=&gt; 2,“updated_at”=&gt;星期四,2012年9月20日06:22:07 UTC +00:00 < /强>}
调用update_attributes之后:
←[36m2012-09-20T08:04:15 + 00:00 app [web.1]:←[0m {“created_at”=&gt; Thu,2012年9月20日00:43:45 UTC +00:00 ,“somefield”=&gt;“10000848364”,“id”=&gt; 2,“updated_at”=&gt;星期四,2012年9月20日06:22:07 UTC +00:00 }
答案 0 :(得分:0)
经过大量艰苦的研究,我设法找出问题的根源和解决方案,但我不清楚为什么这种情况正在发生。尽管如此,它现在还没有阻止我,这就足够了。
在上面的代码中,在
中# <figure out some stuff here>
块。因为我不认为它是相关的,所以我在原始问题中抽象出了代码。事实证明它是。具体来说,有一行我正在进行字符串连接:
some_string << @foo.somestringfield
由于某种原因,这一行引起了
related.update_attributes(stuff)
不保存到数据库。这是100%可重复的(相信我,我测试了大约10次,以确保)。修复很简单:
some_string = some_string + @foo.somestringfield
认真地解决了这个问题。我没有深入调试ruby中的就地连接的内容以确定根本原因,但是如果其他人遇到过这个问题,那么现在你知道了。
答案 1 :(得分:0)
通常看起来这种行为(update_attributes
保存在本地而不是Heroku上)可以通过确保你没有在update_attributes
的调用中执行函数来解决问题。
对我来说,调用update_attributes(:heartbeat => Time.now)
在本地工作并且无法保存在Heroku上。使用上面的答案,我猜测并通过在调用update_attributes之前将Time.now
保存到变量来解决问题:
heartbeat = Time.now
thing.update_attributes(:heartbeat => heartbeat)
此代码在Heroku上正确保存。 这应该是一个评论,但由于声誉规则,我正在回答。'