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

StackOverflow https://stackoverflow.com/questions/818119

  •  03-07-2019
  •  | 
  •  

Вопрос

У меня есть модель с именем Contact, у которой has_one guest, например.

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

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

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

Это было полезно?

Решение

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

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

@contact.guest = @guest

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

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

Сложные формы Railscasts часть 1

Сложные формы Railscasts часть 2

Сложные формы Railscasts часть 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 без необходимости реализовывать сложную форму, чтобы сделать это за вас!

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top