复杂在铁轨上的红宝石中保存关联

时间:2013-03-02 05:35:40

标签: ruby-on-rails activerecord callback ruby-on-rails-3.2 after-save

理论: - 在customer bill创建记录后,我发送两组数据两个不同的模型。一组数据发送到ledger,一组数据发送到ledger_line_item。复杂性是在发送数据后我希望ledger_id存储在ledger_line_item中。代码如下

代码: -

class CustomerBill < ActiveRecord::Base
  after_create :creating_ledger_line_items, :creating_ledger_items

  def creating_ledger_items
    CustomerLedger.create(:customer_id =>self.customer_id,/*rest of attributes*/)
  end

  def creating_ledger_line_items
    CustomerLedgerLineItem.create(:customer_id =>self.customer_id,/*rest of attributes*/)
  end
end

在分类帐中我写过

class CustomerLedger < ActiveRecord::Base
  after_save :update_record_line_items

  def update_record_line_items
    a = CustomerLedgerLineItem.find_by_customer_id(self.customer_id)
    a.update_attributes(:customer_ledger_id => self.id)
  end
end

上述代码正常运行且没有错误,但ledger_id未在ledger_line_items中发布。我无法确定为什么会发生这种错误?有没有其他方法可以实现我在创建账单后在ledger_id中发布ledger_line_items的目标? 需要指导。提前感谢你。

2 个答案:

答案 0 :(得分:0)

您可以按如下方式更改模型:

我假设你有Customer Model

class Customer < ActiveRecord::Base
  has_one :customer_ledger
  has_many :customer_ledger_line_items, :through => :customer_ledger   
  accepts_nested_attributes_for :customer_ledger

end

class CustomerLedger < ActiveRecord::Base
  has_many :customer_ledger_line_items
  accepts_nested_attributes_for :customer_ledger_line_items
end

class CustomerBill < ActiveRecord::Base
  belongs_to :customer
  after_create :creating_ledger_items, :creating_ledger_line_items

  def creating_ledger_line_items
   cl = self.customer.customer_ledger.build(your_attributes)
   cl.save!
  end

  def creating_ledger_items
    cli = self.customer.customer_ledger.customer_ledger_items.build(your_attributes)
    cli.save!     
  end
end

答案 1 :(得分:0)

如果你想在* after_create *钩子上创建模型,我会解释问题是什么。

当你在rails中创建一个模型,并且你有像@ after_create *,* before_update *等钩子时,所有更新都发生在一个Transaction中,所以如果它们中的任何一个抛出异常,则不会更新任何内容。

在这种情况下,在事务中,您正在尝试获取尚不存在的CustomerLedger的ID,因为由于所有内容都在事务中,因此在执行事务之前,记录不会保存到数据库中,这就是在CustomerLedger#update_record_line_items上,self.id始终为零的原因。

使用codeit提出的嵌套属性可能是解决问题的最佳方法,但如果您认为嵌套属性是一个先进的主题,您可以执行以下操作:

class CustomerBill < ActiveRecord::Base

  after_create :created_leder_data

  def create_ledger_data
    customer_ledger = CustomerLedger.build(customer_id: self.customer_id, # Rest of attributes)
    customer_ledger.customer_ledger_line_items.build(customer_id: self.customer_id, # Rest of attributes)
    customer_ledger.save!
  end
end