Ruby on rails Rails:派生类的未知属性错误

Ruby on rails Rails:派生类的未知属性错误,ruby-on-rails,ruby-on-rails-3,Ruby On Rails,Ruby On Rails 3,我有一个名为“PaypalPayment”的型号: class PaypalPayment < PaymentMethod belongs_to :order def provider_class PaypalPayment end def process! end end 但是当我尝试初始化这个模型的对象时,我得到了未知属性:payment\u id @paypal_payment = PaypalPayment.new(:payment_id =&

我有一个名为“PaypalPayment”的型号:

class PaypalPayment < PaymentMethod
  belongs_to :order
  def provider_class
    PaypalPayment
  end

  def process!
  end   
end
但是当我尝试初始化这个模型的对象时,我得到了
未知属性:payment\u 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

我认为您必须在PaymentMethods表中添加“type”列。这将允许它是可继承的。如果没有type列,当您实例化PaypalPayment时,它会认为它是PaymentMethod,因此没有PaypalPayment的唯一字段。但是,当您将“type”列添加到PaymentMethod时,它将存储“PaypalPayment”,ActiveRecord知道如何使PaypalPayment方法可用。您可能还应该为PaymentMethod创建一个模型,并确保它继承ActiveRecord::Base

def change
  add_column :payment_methods, :type, :string
end
以下是一些信息: 我会这样做:

检查Rails控制台--

CheckRails正在拾取该属性

为了测试起见,只需尝试
attr\u accessor:payment\u id
,看看这是否有效。您可能不允许在模型中使用该属性

在Rails4中,这意味着使用
强参数
,但在Rails3中,我认为这意味着使用
attr\u accessible
,如下所示:

#app/models/paypal_payment.rb
Class PaypalPayment < ActiveRecord::Base
    attr_accessible :payment_id #-> tests parameter passing
    attr_accessor :payment_id #-> tests virtual attribute assignment
end
#app/models/paypal_payment.rb
类PaypalPayment测试参数传递
属性访问器:支付id->测试虚拟属性分配
结束

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

  • :所有类都存储在一个表中
  • :所有类都有自己的表
  • :只有具体类才有表(例如,在您的示例中,
    PaymentMethod
    如果是抽象类,则不会有表)
  • 现在是ActiveRecord:单表继承

    所以如果你写

    class PaypalPayment < PaymentMethod
    
    class paympayment
    ActiveRecord将采用STI并查找类型列,此外,将只查找
    payment\u methods
    table

    取决于你想要什么,在大多数情况下,STI就是完美的。有时我更喜欢类和具体表继承,但尤其是对于关联,这需要更多的内部控制,因为:

    • e、 您有不同的付款方式,但它们存储在不同的表中
    • 如果要同时访问所有付款方式,则需要“抽象类”
    • 您需要根据可能的付款方式建立关联
    • 如果你有“抽象类”,你如何链接到“真实支付方法”。一种方法是将表名和子项的id包含为链接
    有很多方法可以解决这个问题,但总是比使用单个表更难。此外,这还扩展了关系数据模型,因为根据所选的解决方案,外键约束不会自动得到支持。我可以说得更详细一些, 但我不确定这是否相关,因为你的例子似乎是STI的经典案例


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

    我知道我在这里的演示有点晚了,但是如果有人在Rails 5.1中遇到类似的问题,在我的例子中,我能够通过在父类中包含以下行来解决这个问题


    self.abstract\u class=true

    尽管数据库有正确的列,但还是值得检查Rails是否知道该列。这可能与初始表的创建方式有关。Rails模式表是什么样子的?@MichaelMoulsdale:schema看起来像`创建表“paypal\u payments”,:force=>true do | t | t.integer“order\u id”t.integer“payment\u id”t.datetime“创建于”t.datetime“更新于”t.string“状态”t.decimal“金额”t.string“cc”t.string“cm”对不起,我想不出别的了。也许值得发布完整的错误输出?@MichaelMoulsdale:这与模型的基类有关吗?当您在rails控制台中键入时会发生什么:@p=payparmament.new@p.payment\u id=1
    id
    payment\u id
    是表中两个独立的列。那么,你是说paypal_payments_payments_id吗?不,你应该可以只使用paypal_payments_id,这就是被关联为id的内容。因此每个表都有一个id,如果你想显式访问该id,你可以将表名放在它前面。现在您也可以将其他id添加到表中,例如使用payment_id在此处完成。(很可能是关联)对不起,我知道您现在正在尝试执行的操作。。。现在再看一遍,这看起来应该是可行的。你能为paypal_payments表显示你的db/schema文件吗?哦,对不起(我的糟糕!)。您应该可以从您的
    PayPayment
    模型中获取
    列名
    。。。您确定继承工作正常吗?获取以下列\u名称-
    [“id”、“type”、“name”、“description”、“active”、“environment”、“created\u at”、“updated\u at”、“deleted\u at”、“display\u on”]
    。是因为
    PaymentMethod
    没有剩余的列吗??如果是这样的话,我怎样才能访问这些属性呢?啊,我现在知道了。所以你只得到你的“主”专栏。你是如何定义这种关系的?这是我想要解决的问题,我已经在模型类中定义了以下关系:
    类PaypalPayment
    对不起,我是说在PaymentMethod模型中?
    def change
      add_column :payment_methods, :type, :string
    end
    
    $ rails c
    $ payment = PaypalPayment.find(1)
    $ payment.column_names #-> should reveal which columns Rails comes back with
    
    #app/models/paypal_payment.rb
    Class PaypalPayment < ActiveRecord::Base
        attr_accessible :payment_id #-> tests parameter passing
        attr_accessor :payment_id #-> tests virtual attribute assignment
    end
    
    class PaypalPayment < PaymentMethod