Rails: atributos virtuais e valores do formulário
-
06-07-2019 - |
Pergunta
Eu tenho um livro Modelo com um atributo virtual para criar um editor do livro. Os olhares código como:
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 a nova forma:
<% 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>
...
Com isso, quando os dados do formulário não passar as validações eu perdi os dados submetidos no campo editorial quando a forma é exibida novamente, e também um novo Editor é criado. Como posso corrigir este dois problemas? Eu sou muito novo em ruby ??e eu não consigo encontrar uma solução.
Atualização meu controlador:
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
Solução
Eu acredito que a sua causa o seu método editorial_string Livro # sempre retornará "". Poderia simplificar ao seguinte:
def editorial_string
editorial ? editorial.name : ""
end
Atualização com base no comentário:
Parece que você quer fazer formulários aninhados. (Veja accepts_nested_attributes_for em api docs ) Nota isto é novo no Rails 2.3.
Então, se você atualizar sua classe Book
class Book < ActiveRecord::Base
accepts_nested_attributes_for :editorial
...
end
(Você também pode agora remover o editorial_string =, editorial_string métodos também)
E atualizar seus formulários para algo como o seguinte
...
<% f.fields_for :editorial do |editorial_form| %>
<%= editorial_form.label :name, 'Editorial:' %>
<%= editorial_form.text_field :name %>
<% end %>
...
Outras dicas
O primeiro problema é que
def editorial_string
self.editorial.name unless editorial.nil?
""
end
sempre retornará "" porque essa é a última linha.
def editorial_string
return self.editorial.name if editorial
""
end
iria corrigir esse problema. Tanto quanto porque as validações não passar, eu não sei, o que está fazendo no controlador? O validação erros você está recebendo?
Dê uma olhada este podcast http://railscasts.com/episodes / 167-mais-on-virtual-atributos . Eu acho que você deve mover o find_or_create do editorial_string = (entrada) método para chamar de volta após o salvamento.