Retain field value of nested form after failed validation

I am new to rails and have not yet been able to solve the following problem. I use a model called "user" for authentication. This model is associated with another model called "company":

user.rb

class User < ActiveRecord::Base devise :database_authenticatable, :registerable, :confirmable, :recoverable, :rememberable, :trackable, :validatable belongs_to :company accepts_nested_attributes_for :company attr_accessible :company_attributes, :email, :password, :password_confirmation, :remember_me, :company_id 

company.rb

  class Company < ActiveRecord::Base has_many :users attr_accessible :name validates :name, :presence => true, :uniqueness => true 

When registering, the user creates both the company and the user:

users_controller.rb

 def new @user = User.new @user.build_company respond_to do |format| format.html # new.html.erb format.json { render json: @user } end end def create @user = User.new(params[:user]) respond_to do |format| if @user.save format.html { redirect_to @user, notice: 'User was successfully created.' } format.json { render json: @user, status: :created, location: @user else format.html { render action: 'new' } format.json { render json: @user.errors, status: :unprocessable_entity } end end end 

Registration still works, which means that if @user.save true, two entries are created in each user model and company model with the correct association in the company_id column in the user model.

If @user.save is false, for example, because authentication for the user attribute does not work, because it has already been completed, a new view is created. As expected, the @user attribute, in this case the email is saved and remains in the corresponding form field after the render action: 'new' . The form field for the company attribute name appears blank. This is the view of the registration page:

new.html.erb

 <%= devise_error_messages! %> <h2>Sign up</h2> <%= simple_form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => {:class => 'form-horizontal' }) do |f| %> <%= f.simple_fields_for :company, @user.build_company do |builder| %> <div><%= builder.label :name, "Company" %><br /> <%= builder.text_field :name, :autofocus => true, :placeholder => "Example Company Inc.", :required => true %></div> <% end %> <div><%= f.label :email %><br /> <%= f.email_field :email, :placeholder => " example@email.com ", :required => true %></div> <div><%= f.label :password %><br /> <%= f.password_field :password, :required => true %></div> <div><%= f.label :password_confirmation %><br /> <%= f.password_field :password_confirmation, :required => true %></div> <%= f.submit "Sign up", :class => "btn"%> <% end %> <%= render "devise/shared/links" %> 

I thought that I might have to create an @company instance @company in the user creation method so that the contents of the form field could be stored in a hash parameter as follows:

 @company = @user.build_company(params[:company]) 

Unfortunately, this does not work, and so far I have not found a solution in other issues posted on stackoverflow. I look forward to your input so that I can continue creating my first application;)

Thanks in advance for your help.

+4
source share
1 answer

Thanks to input from Michal, I rebuilt the controllers so that the user is created through an associated company, and not vice versa. The appropriate company controller is as follows:

companies_controller.rb

 # GET company/new def new @company = Company.new @company.users.build end # POST company/ def create @company = Company.new(params[:company]) respond_to do |format| if @company.save format.html { redirect_to root_path, notice: 'Welcome! Your account has been created successfully. A confirmation link has been sent to your email address.' } format.json { render json: root_path, status: :created, location: @company } else format.html { render action: "new" } format.json { render json: @company.errors, status: :unprocessable_entity } end end end 

The GET request form embeds the Devise User model fields as follows:

new.html.erb

 <h2>Create an account</h2> <%= simple_form_for( @company, :html => {:class => 'form-horizontal' }) do |f| %> <%= render 'shared/error_messages', :object => @company %> <%= f.input :name, :label =>'Company name', :placeholder => "Example Company Inc.", :autofocus => true %> <%= f.simple_fields_for :users do |builder| %> <%= builder.input :email, :placeholder => " example@email.com " %> <%= builder.input :password %> <%= builder.input :password_confirmation %> <% end %> <%= f.button :submit, 'Create account', :class => 'btn'%> <% end %> <%= link_to "Sign in", new_session_path(:user) %> 

Now, if the validation fails, all instance attribute values ​​remain in the corresponding form field.

0
source

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


All Articles