棘手的Rails 4 ActiveRecord继承

时间:2014-07-08 21:39:34

标签: ruby-on-rails ruby inheritance activerecord single-table-inheritance

我创建了几个模型,如下所示。 基本模型是TransactionType和TransactionItem ExpenseType和IncomeType派生自TransactionType。 费用和收入来自TransactionItem。

class TransactionType < ActiveRecord::Base
  scope :expense_types,  -> { where(tran_type: 'ExpenseType') }
  scope :income_types,   -> { where(tran_type: 'IncomeType') }
  self.inheritance_column = "tran_type"
  validates :name, uniqueness: true
end

class ExpenseType < TransactionType
end

class IncomeType < TransactionType
end

class TransactionItem < ActiveRecord::Base
validates :note, length: { in: 2..255 }
end

class Expense < TransactionItem
belongs_to :expense_type
validates :expense_type, presence: true
end

class Income < TransactionItem
belongs_to :income_type
validates :income_type, presence: true
end

我可以为ExpenseType创建对象。 但是,当创建Expense或Income对象时,它会抛出错误。

ExpenseType.new(:name => "Grocceries").save!
ExpenseType.new(:name => "Travel").save!
IncomeType.new(:name => "Salary").save!
IncomeType.new(:name => "Bonus").save!
Expense.new(:note => "a soda", :expense_type => ExpenseType.first)

2.1.2 :006 > Expense.new(:note => "a soda", :expense_type => ExpenseType.first)
  ExpenseType Load (0.1ms)  SELECT  "transaction_types".* FROM "transaction_types"  WHERE "transaction_types"."tran_type" IN ('ExpenseType')  ORDER BY "transaction_types"."id" ASC LIMIT 1
ActiveModel::MissingAttributeError: can't write unknown attribute `expense_type_id'
from /Users/masc/.rvm/gems/ruby-2.1.2/gems/activerecord-4.1.4/lib/active_record/attribute_methods/write.rb:93:in `write_attribute_with_type_cast'
from /Users/masc/.rvm/gems/ruby-2.1.2/gems/activerecord-4.1.4/lib/active_record/attribute_methods/write.rb:58:in `write_attribute'
from /Users/masc/.rvm/gems/ruby-2.1.2/gems/activerecord-4.1.4/lib/active_record/attribute_methods/dirty.rb:68:in `write_attribute'
from /Users/masc/.rvm/gems/ruby-2.1.2/gems/activerecord-4.1.4/lib/active_record/attribute_methods.rb:392:in `[]='
from /Users/masc/.rvm/gems/ruby-2.1.2/gems/activerecord-4.1.4/lib/active_record/associations/belongs_to_association.rb:70:in `replace_keys'
from /Users/masc/.rvm/gems/ruby-2.1.2/gems/activerecord-4.1.4/lib/active_record/associations/belongs_to_association.rb:14:in `replace'
from /Users/masc/.rvm/gems/ruby-2.1.2/gems/activerecord-4.1.4/lib/active_record/associations/singular_association.rb:17:in `writer'
from /Users/masc/.rvm/gems/ruby-2.1.2/gems/activerecord-4.1.4/lib/active_record/associations/builder/association.rb:118:in `expense_type='
from /Users/masc/.rvm/gems/ruby-2.1.2/gems/activerecord-4.1.4/lib/active_record/attribute_assignment.rb:45:in `public_send'
from /Users/masc/.rvm/gems/ruby-2.1.2/gems/activerecord-4.1.4/lib/active_record/attribute_assignment.rb:45:in `_assign_attribute'
from /Users/masc/.rvm/gems/ruby-2.1.2/gems/activerecord-4.1.4/lib/active_record/attribute_assignment.rb:32:in `block in assign_attributes'
from /Users/masc/.rvm/gems/ruby-2.1.2/gems/activerecord-4.1.4/lib/active_record/attribute_assignment.rb:26:in `each'
from /Users/masc/.rvm/gems/ruby-2.1.2/gems/activerecord-4.1.4/lib/active_record/attribute_assignment.rb:26:in `assign_attributes'
from /Users/masc/.rvm/gems/ruby-2.1.2/gems/activerecord-4.1.4/lib/active_record/core.rb:455:in `init_attributes'
from /Users/masc/.rvm/gems/ruby-2.1.2/gems/activerecord-4.1.4/lib/active_record/core.rb:198:in `initialize'
from /Users/masc/.rvm/gems/ruby-2.1.2/gems/activerecord-4.1.4/lib/active_record/inheritance.rb:30:in `new'

如果有人分享你解决这个问题的想法,那将会很棒。

谢谢, MASC

1 个答案:

答案 0 :(得分:1)

如果Expense属于ExpenseType,则费用表需要一个整数属性expense_type_id。

您可以使用

添加它
 rails g migration AddExpenseTypeToExpense expense_type_id:integer

然后rake db:migrate

同样适用于收入和收入类型