[英]Using rails associations for models (undefined method `has_one')
我正在尝试打开注册页面以创建一个帐户(其中有付款),但出现此错误“Account:Class 的未定义方法‘has_one’”。 我没有使用数据库,所以我没有使用活动记录。 有没有解决的办法?
账号.rb
class Account
include ActiveModel::Model
attr_accessor :company_name, :phone_number,
:card_number, :expiration_month, :expiration_year, :cvv
has_one :payment
end
付款.rb
class Payment
include ActiveModel::Model
attr_accessor :card_number, :expiration_month, :expiration_year, :cvv
belongs_to :account
validates :card_number, presence: true, allow_blank: false
validates :cvv, presence: true, allow_blank: false
end
account_controller.rb
class AccountController < ApplicationController
def register
@account = Account.new
end
end
has_one
和belongs_to
不是ActiveModel::Model
一部分。 它们是ActiveRecord
一部分,因为它们指定了如何从关系数据库中获取对象。
在您的情况下,我想您应该在Account
模型中有另一个属性payment
。
class Account
include ActiveModel::Model
attr_accessor :company_name, :phone_number,
:card_number, :expiration_month,
:expiration_year, :cvv,
:payment
end
然后在你的控制器中做类似的事情
class AccountController < ApplicationController
def register
@account = Account.new
@account.payment = Payment.new
end
end
或者您可以在Account
类的初始化程序中事件初始化付款。 似乎Payment
也不需要知道Account
。
当然,这是一个非常古老的问题,但我在尝试解决类似问题时遇到了它,最终发现在此期间出现了解决方案。 因此,鉴于唯一发布的答案从未被标记为“已接受”,我想我会扔掉我的帽子。
Rails 5 引入了 ActiveRecord Attributes API, 通过 Karol Galanciak的这篇文章描述它,您可能有兴趣看一看由同一作者创建的gem 。 如果您查看了该 gem 的问题,您可能有兴趣阅读issue #12中的 Attributes API 功能现在存在于 ActiveModel 中,尽管它没有公开记录( module Attributes
被标记为#:nodoc:
,请参阅attributes.rb ) 并且也许不应该依赖于版本与版本之间的一致性,尽管有时看起来很柔和的风肯定是朝着“公共” ActiveModel::Attributes
的方向吹的应用程序接口。
尽管如此,如果您要谨慎行事并使用不完全公开的ActiveModel::Attributes
您可以执行以下操作(注意:我为自己的项目拼凑了这些,并稍微重写了一下以适合您的示例,您的需求可能与我的不同):
class AccountPayment
include ActiveModel::Model
attr_accessor :card_number, :expiration_month, :expiration_year, :cvv
validates :card_number, presence: true, allow_blank: false
validates :cvv, presence: true, allow_blank: false
end
class AccountPaymentType < ActiveModel::Type::Value
def cast(value)
AccountPayment.new(value)
end
end
class Account
include ActiveModel::Model
include ActiveModel::Attributes #being bad and using private API!
attr_accessor :company_name, :phone_number, :card_number, :expiration_month, :expiration_year, :cvv
attribute :payment, :account_payment
end
在某个地方你必须注册类型 - 在 rails 中它会在一个初始化器中,但在我的代码中我只是将它藏在你的Account
模型的顶部:
ActiveModel::Type.register(:account_payment, AccountPaymentType)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.