Rotaie: attributi virtuali e valori dei moduli
-
06-07-2019 - |
Domanda
Ho un libro modello con un attributo virtuale per creare un editor dal modulo Libro. Il codice è simile a:
class Book < ActiveRecord::Base
has_many :book_under_tags
has_many :tags, :through => :book_under_tags
has_one :editorial
has_many :written_by
has_many :authors, :through => :written_by
def editorial_string
self.editorial.name unless editorial.nil?
""
end
def editorial_string=(input)
self.editorial = Editorial.find_or_create_by_name(input)
end
end
E il nuovo modulo:
<% form_for(@book,
:html => { :multipart => true }) do |f| %>
<%= f.error_messages %>
...
<p>
<%= f.label :editorial_string , "Editorial: " %><br />
<%= f.text_field :editorial_string, :size => 30 %> <span class="eg">Ej. Sudamericana</span>
</p>
...
Con questo, quando i dati del modulo non superano le convalide ho perso i dati inviati nel campo editoriale quando il modulo viene visualizzato di nuovo e viene creato anche un nuovo editor. Come posso risolvere questi due problemi? Sono abbastanza nuovo in ruby ??e non riesco a trovare una soluzione.
AGGIORNA il mio controller:
def create
@book = Book.new(params[:book])
respond_to do |format|
if @book.save
flash[:notice] = 'Book was successfully created.'
format.html { redirect_to(@book) }
format.xml { render :xml => @book, :status => :created, :location => @book }
else
format.html { render :action => "new" }
format.xml { render :xml => @book.errors, :status => :unprocessable_entity }
end
end
end
Soluzione
Credo che la causa sia che il metodo Book # editorial_string restituirà sempre " " ;. Potrebbe semplificare a quanto segue:
def editorial_string
editorial ? editorial.name : ""
end
Aggiornamento basato sul commento:
Sembra che tu voglia fare moduli nidificati. (Vedi accetta_nested_attributes_per in api docs ) Nota che è nuovo in Rotaie 2.3.
Quindi, se aggiorni la tua classe di libri
class Book < ActiveRecord::Base
accepts_nested_attributes_for :editorial
...
end
(Ora puoi anche rimuovere i metodi editorial_string =, editorial_string)
E aggiorna i tuoi moduli a qualcosa di simile al seguente
...
<% f.fields_for :editorial do |editorial_form| %>
<%= editorial_form.label :name, 'Editorial:' %>
<%= editorial_form.text_field :name %>
<% end %>
...
Altri suggerimenti
Il primo problema è quello
def editorial_string
self.editorial.name unless editorial.nil?
""
end
restituirà sempre " " perché questa è l'ultima riga.
def editorial_string
return self.editorial.name if editorial
""
end
risolverebbe questo problema. Per quanto riguarda il motivo per cui le convalide non passano, non lo so, cosa stai facendo nel controller? Quali errori di convalida stai riscontrando?
Dai un'occhiata a questo podcast http://railscasts.com/episodes / 167-più-on-virtual-attributi . Penso che dovresti spostare find_or_create da editorial_string = (input) metodo per richiamare dopo il salvataggio.