Domanda

Ho un modello chiamato Contact che ha come_one guest in questo modo.

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

Nella mia vista di creazione sto usando il metodo di selezione dell'helper per elencare tutti i Contatti che possono essere scelti come ospiti in questo modo ...

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

Ogni volta che questo modulo viene inviato ricevo un errore che dice che era in attesa di un contatto ma che aveva una stringa.

Dove e come devo convertire la stringa inviata dal modulo in un contatto prima di salvare il contatto corrente nel database?

È stato utile?

Soluzione

Quando crei un'associazione in Rails, come has_one, ci sono alcuni metodi che vengono generati dinamicamente per il tuo oggetto per un facile assegnamento.

Al momento, il metodo che stai utilizzando è

@contact.guest = @guest

E l'oggetto contatto si aspetta di ricevere un altro oggetto ActiveRecord a cui potrebbe associarsi. Quello che stai cercando di fare, però, è gentile "falso" questo metodo nel tuo modulo che avvolge un oggetto modello. (Le informazioni che arrivano dai parametri sono inserite come una stringa, motivo per cui stai ricevendo quell'errore)

Esistono diversi modi per implementare questo. Il primo con sta usando gli attributi del modello nidificato. . . moduli complessi che consentono di racchiudere un'associazione figlio all'interno del form_for che si sta utilizzando (utilizzando l'helper del modulo fields_for ). Una spiegazione di questo richiederebbe molto tempo per scrivere, e fortunatamente ci sono incredibili risorse gratuite in forme complesse:

Railscasts Complex Forms part 1

Railscasts Complex Forms part 2

Railscasts Complex Forms part 3

Inoltre, se stai usando Rails 2.3, controlla alcune informazioni su " accetta_nested_attributes_for " . . . C'è una netta mancanza di tutorial là fuori in questo momento, ma immagino che con l'uscita di 2.3 ce ne saranno molti in arrivo. Questo piccolo aiuto utile eliminerà circa la metà del codice che Ryan usa nelle sue schermate per far sì che le forme accettino un modello secondario.

Infine c'è una soluzione alternativa. Se la tua relazione è semplice, se gli ospiti che desideri associare sono già nel database e non hai bisogno di crearne di nuovi dal modulo che stai utilizzando, puoi utilizzare qualcosa come un attributo virtuale. Nel tuo modulo, cambia semplicemente f.select: guest in qualcosa come f.select: guest_select e implementa un metodo nel tuo modello:

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

Che assegnerà il modello ActiveRecord senza dover implementare un modulo complesso per farlo per te!

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top