Pergunta

Eu tenho um modelo chamado Contactar que hóspedes has_one assim.

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

Na minha criar vista Eu estou usando o seleto método auxiliar para listar todos os contatos que podem ser escolhidos como convidado assim ...

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

Sempre que este formulário é enviado eu recebo um erro dizendo que estava esperando um contato, mas tenho um string.

Onde e como devo converter a seqüência apresentada pelo formulário para um contato antes de salvar o contato atual para o banco de dados?

Foi útil?

Solução

Quando você cria uma associação no Rails, como has_one, existem alguns métodos que um gerados dinamicamente para o seu objeto para facilitar a tarefa.

Agora, o método que você está usando é

@contact.guest = @guest

E o seu objeto de contato está esperando para receber outro objeto ActiveRecord que pode associar-se. O que você está tentando fazer, porém, é tipo "fake" este método em seu formulário que envolve um objeto de modelo. (A informação vindo do params é trazido como uma string, e é por isso que você está recebendo esse erro)

Existem várias maneiras que você poderia ir sobre como implementar esta. A primeira é com o uso de atributos modelo aninhados. . . formas complexas que permitem que você enrole uma associação de crianças dentro da form_for você está usando (usando o formulário fields_for helper). Uma explicação sobre isso levaria muito tempo para escrever, e, felizmente, existem incríveis recursos livres em formas complexas:

Railscasts formas complexas parte 1

Railscasts formas complexas parte 2

Railscasts formas complexas parte 3

Além disso, se você estiver usando o Rails 2.3, então confira algumas informações sobre "accepts_nested_attributes_for". . . Há uma clara falta de tutoriais lá fora agora, mas eu imagino que com o lançamento do 2.3 não vão ser muito vinda. Este pequeno ajudante prático vai cortar cerca de metade do código Ryan usos em seus elencos de tela para fazer formas aceitar um modelo subbordinate.

Finalmente, há uma solução alternativa. Se o seu relacionamento é simples, se os convidados que você deseja associar já estão no banco de dados, e você não precisa criar novos de forma que você está usando, então você pode usar algo como um atributo virtual. Em seu formulário, basta alterar o seu f.select :guest para algo como f.select :guest_select e implementar um método no seu modelo:

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

O que irá atribuir o modelo ActiveRecord sem ter que implementar uma forma complexa para fazer isso por você!

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top