Rails: virtual attributes and form values

I have a model book with a virtual attribute to create an editor from a book form. The code looks like this:

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 a 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> ... 

At the same time, when the form data does not pass the verification, I lost the data sent to the editorial field when the form was repeated, and a new editor was created. How can I solve these two problems? I am new to ruby ​​and I cannot 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 
+4
source share
3 answers

I believe your Book # editorial_string method will always return "". The following can be simplified:

  def editorial_string editorial ? editorial.name : "" end 

Comment based update:

It looks like you want to do nested forms. (See accepts_nested_attributes_for in the api docs ) Note that this is new in Rails 2.3.

So if you update your Book class

 class Book < ActiveRecord::Base accepts_nested_attributes_for :editorial ... end 

(Now you can also remove the methods editorial_string =, editorial_string)

And update your forms something like this:

 ... <% f.fields_for :editorial do |editorial_form| %> <%= editorial_form.label :name, 'Editorial:' %> <%= editorial_form.text_field :name %> <% end %> ... 
+3
source

The first problem is that

 def editorial_string self.editorial.name unless editorial.nil? "" end 

will always return "because this is the last line.

 def editorial_string return self.editorial.name if editorial "" end 

will fix this problem. As for why the checks fail, I don’t know what you are doing in the controller? What verification errors do you get?

+1
source

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 after saving.

0
source

Source: https://habr.com/ru/post/1286529/


All Articles