我有2个表产品和历史记录
产品表:
id name type price location 1 abc electronics $200 aisle1
历史表:
id product_id status 1 1 price changed from $200 to $180
每当用户通过点击更新按钮更新产品价格或位置时,更改应自动反映在历史状态列中,而无需用户手动输入。
如果价格从200更新为180,那么将使用新ID创建新的历史记录行,状态列将显示“价格从200美元变为180美元”。
如果位置从aisle1更新到过道2,则状态显示'loc从aisle1更改为过道2'。
我试过了:
@product = Product.new(params[:product])
@history = History.new(params[:history])
if @product.save
@history.new(attributes) # I am not sure of whether this approach is correct
如果有人能告诉我在这种情况下如何自动更新历史记录,我真的很感激。
答案 0 :(得分:3)
您想要的是使用Observer。
你可以像这样设置一个:
class ProductObserver < ActiveRecord::Observer
def after_save(product)
#get attributes here
history.new(attributes)
history.save
end
end
请注意,您必须手动指定在环境配置中加载哪些观察者;你不能简单地添加文件并让它工作。
答案 1 :(得分:3)
在产品型号中添加after_save
过滤器。
class Product < ActiveRecord::Base
after_save :make_history
has_many :histories
def make_history
status = ""
status << "Price changed from #{price_was} to #{price}" if price_changed?
status << "Location changed from #{location_was} to #{location}" if location_changed?
return if status.empty?
errors = histories.create(:status = status).errors.full_messages.join(",\n")
# return true if no error
return true if errors.empty?
# Roll the error to base
errors.add_to_base("History creation error:\n#{errors}")
# explicitly rollback
raise ActiveRecord::Rollback
# return false to terminate the callback chain
return false
end
end
修改强>
我添加了代码,以便在Product
创建失败时回滚History
。
答案 2 :(得分:0)
一种方法是在模型上使用after_save回调。将其添加到您的产品ActiveRecord模型:
after_save :update_history
def update_history
do_whatever
end
查看here。