I have a Model Book with a virtual attribute for create a Editor from the Book form. The code looks like:
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
And the new form:
<% 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>
...
With this, when the form data no pass the validations I lost the data submited in the editorial field when the form is redisplayed, and also a new Editor is created. How I can fix this two problems? I am pretty new in ruby and I can't find a solution.
UPDATE my 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
I believe its cause your Book#editorial_string method will always return "". Could simplify to the following:
Update based on comment:
Sounds like you want to do nested forms. (See accepts_nested_attributes_for in api docs) Note this is new in Rails 2.3.
So if you update your Book class
(You could also now remove the editorial_string=, editorial_string methods too)
And update your forms to something like the following
The first problem is that
will always return "" because that is the last line.
would fix that problem. As far as why the validations don't pass, I don't know, what are you doing in the controller? What validation errors are you getting?
Take a look at this podcast http://railscasts.com/episodes/167-more-on-virtual-attributes. I think you should move your find_or_create from the editorial_string=(input) method to call back after the save.