Ruby-on-rails Rails 如何在保存后更新列?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5777172/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Rails how to update a column after saving?
提问by Rails beginner
I want to create an after_save method for my rate action. It would divide rating_score/ratings and update the column rating.
我想为我的费率操作创建一个 after_save 方法。它将划分 rating_score/ ratings 并更新列评级。
class KonkurrancersController < ApplicationController
def rate
@konkurrancer = Konkurrancer.find(params[:id])
@container = "Konkurrancer"[email protected]_s
@konkurrancer.rating_score += params[:vind][:rating].to_i
@konkurrancer.ratings += 1
@konkurrancer.save
respond_to do |format|
format.js
end
end
end
This is my model:
这是我的模型:
class Konkurrancer < ActiveRecord::Base
after_save :do_foobar
private
def do_foobar
rating_score = self.rating_score
ratings = self.ratings
rating = (rating_score/ratings)
self.update_attributes(:rating => rating)
end
end
My rails log:
我的导轨日志:
Started POST "/konkurrancers/rate/46" for 127.0.0.1 at 2011-04-26 23:40:56 +0200
Processing by KonkurrancersController#rate as */*
Parameters: {"utf8"=>"?£?", "authenticity_token"=>"MACFM37hX4S6XA9vryn7gtfl21P
vcaPBSiKDI8mfurg=", "vind"=>{"rating"=>"4"}, "id"=>"46"}
←[1m←[36mKonkurrancer Load (1.0ms)←[0m ←[1mSELECT `konkurrancers`.* FROM `kon
kurrancers`←[0m
←[1m←[35mCACHE (0.0ms)←[0m SELECT `konkurrancers`.* FROM `konkurrancers`
←[1m←[36mCACHE (0.0ms)←[0m ←[1mSELECT `konkurrancers`.* FROM `konkurrancers`←
[0m
←[1m←[35mKonkurrancer Load (1.0ms)←[0m SELECT `konkurrancers`.* FROM `konkurr
ancers` WHERE (`konkurrancers`.`cached_slug` = '46') LIMIT 1
←[1m←[36mSQL (2.0ms)←[0m ←[1mSELECT sluggable_id FROM slugs WHERE ((slugs.slu
ggable_type = 'Konkurrancer' AND slugs.name = '46' AND slugs.sequence = 1))←[0m
←[1m←[35mKonkurrancer Load (1.0ms)←[0m SELECT `konkurrancers`.* FROM `konkurr
ancers` WHERE (`konkurrancers`.`id` = 46) LIMIT 1
←[1m←[36mSQL (0.0ms)←[0m ←[1mBEGIN←[0m
←[1m←[35mLink Load (1.0ms)←[0m SELECT `links`.* FROM `links` WHERE (`links`.k
onkurrancer_id = 46) LIMIT 1
←[1m←[36mSQL (0.0ms)←[0m ←[1mROLLBACK←[0m
Rendered konkurrancers/_rating.html.erb (1.0ms)
Rendered konkurrancers/rate.js.erb (22.0ms)
Completed 200 OK in 606ms (Views: 286.0ms | ActiveRecord: 6.0ms)
How should I create this?
我应该如何创建这个?
采纳答案by Christian Fazzini
what you want is a callback. You can create an after_save callback on your Konkurrancer model, which triggers after the save()method is called for that model.
你想要的是回调。您可以在 Konkurrancer 模型上创建 after_save 回调,该回调在为该模型调用save()方法后触发。
For example:
例如:
class Konkurrancer < ActiveRecord::Base
after_save :do_foobar
private
def do_foobar
rating_score = self.rating_score
ratings = self.ratings
rating = (rating_score/ratings)
self.update_attributes(:ratings => rating)
end
end
[EDIT]You should use self, since the model you are editing is the model itself. Test it out, and apply necessary logic/implementation.
[编辑]您应该使用self,因为您正在编辑的模型是模型本身。对其进行测试,并应用必要的逻辑/实现。
Have a look at this guidefor more info.
查看本指南了解更多信息。
Hope that helps!
希望有帮助!
回答by zakelfassi
Any update_attributein an after_savecallback will cause recursion, in Rails3+.
What should be done is:
在 Rails3+update_attribute中,after_save回调中的任何内容都会导致递归。应该做的是:
after_save :updater
# Awesome Ruby code
# ...
# ...
private
def updater
self.update_column(:column_name, new_value) # This will skip validation gracefully.
end
回答by Mike Bethany
Not sure why people are upvoting the wrong answer and downvoting the correct answer.
不知道为什么人们对错误的答案投赞成票而对正确的答案投反对票。
Zakelfassi is right and Christian Fazzini is wrong for Rails 3 and above. If you do #update_attributes in a save callback you go into an endless recursion. You want to do #update_column as per his example.
对于 Rails 3 及以上版本,Zakelfassi 是对的,而 Christian Fazzini 是错的。如果您在保存回调中执行 #update_attributes,您将进入无限递归。你想按照他的例子做 #update_column 。
Try it for yourself and you'll see.
亲自尝试一下,你就会看到。
回答by Naveed
@konkurrancer.update_attributes :ratings=>'updated value'
回答by TH Afridi
see this after_save method
看到这个after_save 方法

