Как я могу заставить form.select возвращать модель в Rails? - PullRequest
2 голосов
/ 04 мая 2009

У меня есть модель с именем Contact, у которой есть один гость.

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

В моем представлении создания я использую метод выбора помощника, чтобы перечислить все контакты, которые можно выбрать в качестве гостя, например ...

<% 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 %>

Всякий раз, когда эта форма отправляется, я получаю сообщение о том, что он ожидал контакта, но получил строку.

Где и как мне преобразовать строку, представленную в форме, в контакт, прежде чем сохранить текущий контакт в базе данных?

1 Ответ

6 голосов
/ 04 мая 2009

Когда вы создаете ассоциацию в Rails, например has_one, существуют определенные методы, которые динамически генерируются для вашего объекта для легкого назначения.

Сейчас вы используете метод

@contact.guest = @guest

И ваш контактный объект ожидает получения другого объекта ActiveRecord, с которым он может ассоциировать себя. Однако вы пытаетесь «подделать» этот метод в своей форме, который обернет объект модели. (Информация, поступающая из параметров, вводится в виде строки, поэтому вы получаете эту ошибку)

Есть несколько способов реализовать это. Первый с использованием атрибутов вложенной модели. , , сложные формы, которые позволяют вам обернуть дочернюю ассоциацию в form_for, который вы используете (используя помощник по формам fields_for). Для объяснения этого потребуется много времени, и, к счастью, в сложных формах есть невероятные бесплатные ресурсы:

Railscasts Complex Forms part 1

Railscasts Complex Forms part 2

Railscasts Complex Forms part 3

Также, если вы используете Rails 2.3, ознакомьтесь с информацией о "accepts_nested_attributes_for". , , Сейчас явно не хватает учебных пособий, но я думаю, что с выпуском 2.3 их будет много. Этот удобный маленький помощник будет вырезать примерно половину кода, который Райан использует в своих скриншотах, чтобы формы принимали подчиненную модель.

Наконец, есть обходной путь. Если ваши отношения просты, если гости, которых вы хотите связать, уже находятся в базе данных, и вам не нужно создавать новых из формы, которую вы используете, тогда вы можете использовать что-то вроде виртуального атрибута. В вашей форме просто измените ваш 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 без необходимости реализовывать сложную форму, чтобы сделать это за вас!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...