我有一个名为 PaypalPayment 的模型:

class PaypalPayment < PaymentMethod
  belongs_to :order
  def provider_class
    PaypalPayment
  end

  def process!
  end
end

我为它生成了以下迁移:
class CreatePaypalPayments < ActiveRecord::Migration
  def change
    create_table :paypal_payments do |t|
      t.integer :order_id
      t.integer :payment_id

      t.timestamps
    end
  end
end


class AddDetailsToPaypalPayment < ActiveRecord::Migration
  def change
    add_column :paypal_payments, :state, :string
    add_column :paypal_payments, :amount, :decimal
    add_column :paypal_payments, :cc, :string
    add_column :paypal_payments, :cm, :string
  end
end

迁移后,该表如下所示:
development_database=# select * from paypal_payments;
 id | order_id | payment_id | created_at | updated_at | state | amount | cc | cm

但是当我尝试初始化这个模型的一个对象时,我得到了 unknown attribute: payment_id
@paypal_payment = PaypalPayment.new(:payment_id => params[:tx], :state => params[:st], :cc => params[:cc], :cm => params[:cm], :order_id => params[:id])

编辑: db/schema.rb:
create_table "paypal_payments", :force => true do |t|
    t.integer "order_id"
    t.integer "payment_id"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.string "state"
    t.decimal "amount"
    t.string "cc"
    t.string "cm"
end

最佳答案

在关系数据库中有多种建模继承的方法,Martin Fowler 列出了以下选项:

  • Single Table Inheritance : 所有类都存储在一个表中
  • Class Table Inheritance : 所有类都有自己的表
  • Concrete Table Inheritance :只有具体的类有一个表(例如,在你的例子中 PaymentMethod 如果是抽象的,就不会有表)

  • 现在 ActiveRecord only supports STI :单表继承。

    所以如果你写
    class PaypalPayment < PaymentMethod
    

    ActiveRecord 将假定 STI 并查找类型列,此外,只会查找 payment_methods 表。

    根据您的需求,在大多数情况下,STI 是完美的。有时我更喜欢类和具体表继承,但特别是对于协会,这需要更多的家庭管理,因为:
  • 例如您有不同的付款方式,但它们存储在不同的表中
  • 你想一次访问所有支付方式吗,你需要“抽象类”
  • 您需要根据可能的付款方式关联
  • 如果你有“抽象类”,你如何链接到“真实支付方式”。一种方法是将 child 的表名和 id 作为链接包含在内。

  • 有很多方法可以解决这个问题,但总是比使用单个表更难。这也是拉伸(stretch)关系数据模型,因为根据选择的解决方案,不会自动支持外键约束。可以详细说一下
    但我不确定这是否相关,因为您的示例似乎是 STI 的经典案例。

    如果您确实想使用类表继承或具体表继承,每个类都必须从“ActiveRecord::Base”派生,如果需要,您应该包含一个具有共享行为的模块(或关注点)(因为 ruby​​ 不支持多个遗产)。

    关于ruby-on-rails - Rails : unknown attribute error for derived class,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23333779/

    10-13 01:00