Rails同时创建和更新2个模型记录

时间:2010-03-19 22:09:13

标签: ruby-on-rails

我有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

如果有人能告诉我在这种情况下如何自动更新历史记录,我真的很感激。

3 个答案:

答案 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