从rails中的模型访问has_many对象

时间:2014-09-03 15:47:05

标签: ruby-on-rails ruby-on-rails-3

我有三个模型PayrollAllowanceDeduction。此处Payroll的关系为has_many allowances和has_many deductions

Payroll模型具有以下架构

# == Schema Information
#
# Table name: payrolls
#
#  id         :integer         not null, primary key
#  empno      :string(255)
#  name       :string(255)
#  created_at :datetime        not null
#  updated_at :datetime        not null
#  totsal     :decimal(, )

,模型如下

  class Payroll < ActiveRecord::Base
  attr_accessible :empno, :name,:allowances_attributes,:deductions_attributes
  has_many :allowances, dependent: :destroy
  has_many :deductions, dependent: :destroy
  accepts_nested_attributes_for :allowances,allow_destroy: true
  accepts_nested_attributes_for :deductions,allow_destroy: true
  validates :empno, presence: true, uniqueness:{ case_sensitive: false }
  validates_length_of :empno, :minimum => 5, :maximum => 5
  before_save :create_fullname
  before_save :saltotal
  def create_fullname
    emp = Employee.find_by_empno(self.empno)
    self.name= "#{emp.first_name} #{emp.last_name}"   
  end

deduction.rb

# == Schema Information
#
# Table name: deductions
#
#  id         :integer         not null, primary key
#  empno      :string(255)
#  amount     :decimal(, )
#  dtype      :string(255)
#  dedtype    :string(255)
#  payroll_id :integer
#  created_at :datetime        not null
#  updated_at :datetime        not null
#
class Deduction < ActiveRecord::Base
  belongs_to :payroll
  attr_accessible :amount, :dedtype, :empno, :dtype
end

allowance.rb

# == Schema Information
#
# Table name: allowances
#
#  id         :integer         not null, primary key
#  empno      :string(255)
#  amount     :decimal(, )
#  atype      :string(255)
#  payroll_id :integer
#  created_at :datetime        not null
#  updated_at :datetime        not null
#
class Allowance < ActiveRecord::Base
  belongs_to :payroll
  attr_accessible :amount, :empno, :atype
end

我从payrolls控制器处理的单个表单中获取所有这些的值,它运行良好。

现在我正在尝试使用扣除和限额中的值来计算总薪水,并将其存储在totsal模型中的Payroll变量中。

所以我在模型中写了一个before_save函数。但是我面临的问题是如何从模型中的函数中嵌套属性访问变量。以下是我写的但是它不起作用:

def saltotal
    self.allowances do |allowance|
      self.totsal+=allowance.amount
    end
    self.deductions do |deduction|
      self.totsal-=deduction.amount
    end  
    self.totsal
  end

当我从rails控制台检查值时,我看到totsal的值为nil。 那么我应该如何实际访问它。我还尝试添加.eachself.allowances.each do),但它返回错误,说没有这样的方法。我怎么想这样做。

2 个答案:

答案 0 :(得分:0)

由于您的从属对象在父级保存之前未保存,因此您将无法获得self.allowancesself.deductions的值。因此,尝试使用after_save上的观察者来解决您的问题。您必须在观察者中更新对象。希望这有帮助。

答案 1 :(得分:0)

这是由于ForgetTheNorm在评论中指出的一个愚蠢的错误造成的。

我没有初始化self.totsal。在函数self.totsal ||= 0.0的开头添加saltotal解决了这个问题。