Setter但没有使用Mongoid + ActiveModel引用属性的getter

时间:2013-12-07 01:22:49

标签: mongoid activemodel

我有一个Invoice(belongs_to:contact)和一个Contact(has_many:发票)。 在新的发票表单中,我想引用它所属的联系人。为此,请填写以下字段:

<input name='invoice[contact]' type='text'>

当我写下联系人的ID时,哪个有效。没有问题。但是,我希望它能够与联系人的名称一起使用。所以我在 Invoice 中添加了以下回调:

before_save do |invoice|
  invoice.contact = Contact.find_by(name: invoice.contact)
end

但是, invoice.contact 结果为零(尽管输入字段不为空),由于没有与名称联系而引发错误:nil。

以下工作:

before_save do |invoice|
  invoice.contact = Contact.find_by(name: 'some name')
end

before_save do |invoice|
  invoice.contact = Contact.find('52a233b585c4f0fa7d000001')
end

这让我相信有一个invoice.contact的设定者,但不是吸气剂。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

如果您使用虚拟属性作为名称,我认为您会有更好的运气,否则我认为当有人试图将'Bob Dobbs'这样的名称视为ObjectId时,您会遇到问题。你的形式是这样的:

<input name='invoice[contact_name]' type='text'>

然后在你的Mongoid模型中:

attr_reader :contact_name
attr_accessible :contact_name
before_save do |invoice|
  invoice.contact = Contact.find_by(name: invoice.contact_name)
end

这应该会将invoice_contact_name中的联系人姓名作为字符串给你,并且没有任何东西会尝试将其解释为字符串以外的其他内容。

我可能会放弃before_save挂钩并将Contact.find_by移到before_validation,然后您可以验证您有contact_id并且有机会检测到错误的contact_name

attr_reader :contact_name
attr_accessible :contact_name
before_validation :lookup_contact_name
validate_presence_of :contact_id

def lookup_contact_name
  # Some sort of `contact_name` cleanup might be a good idea in here too.
  self.contact = Contact.find_by(name: contact_name)
end