我有一个名为“联系人”的模型,其中有一位客人。

class Contact < ActiveRecord::Base
  has_one :guest, :class_name => "Contact", :foreign_key => "guest"
end

在我的创建视图中,我使用select helper方法列出所有可以作为访客选择的联系人,如此...

<% form_for(@contact) do |f| %>
  <%= f.error_messages %>
    ...
    <p>
        <%= f.label :guest %><br />
        <% @guests = Contact.find(:all, :order => "lastname").map { |u| [u.lastname + ', ' + u.firstname, u.id] } %>
        <%= f.select :guest, @guests, {:include_blank => true} %>
    </p>
    ...
<% end %>

每当提交此表单时,我都会收到一条错误消息,说它正在等待联系但是有一个字符串。

在将当前联系人保存到数据库之前,我应该在何处以及如何将表单提交的字符串转换为联系人?

有帮助吗?

解决方案

在Rails中创建关联时,例如has_one,有一些为对象动态生成的方法,以便于分配。

目前,您使用的方法是

@contact.guest = @guest

并且您的联系对象期望接收可能与其关联的另一个ActiveRecord对象。你想做什么,是善意的“假的”。包装模型对象的表单中的此方法。 (来自params的信息以字符串形式出现,这就是你得到错误的原因)

有几种方法可以实现这一点。第一个是使用嵌套模型属性。 。 。复杂的表单,允许您在正在使用的 form_for 中包装子关联(使用 fields_for 表单帮助程序)。对此进行解释需要花费很长时间才能打字,幸运的是,复杂表格上有令人难以置信的免费资源:

Railscasts复杂表格第1部分

Railscasts复杂表格第2部分

Railscasts复杂表格第3部分

此外,如果您使用的是Rails 2.3,请查看有关“ accepts_nested_attributes_for ”的一些信息。 。 。 。现在有一个明显缺乏教程,但我想,随着2.3的发布,将有很多即将到来。这个方便的小助手将削减Ryan在他的屏幕演员中使用的代码的大约一半,以使表单接受一个次级模型。

最后有一个解决方法。如果您的关系很简单,如果要关联的guest虚拟机已经在数据库中,并且您不需要从正在使用的表单中创建新的guest虚拟机,那么您可以使用类似虚拟属性的内容。在您的表单中,只需将 f.select:guest 更改为 f.select:guest_select ,并在模型中实现方法:

def guest_select=(incoming_id_from_form)
  contact = Contact.find(incoming_id_from_form)
  self.guest = contact
end

这将分配ActiveRecord模型,而无需为您执行复杂的表单!

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top