Using simple_form for nested attributes models in a has_many relation for only new records

Using simple_form for nested attributes models in a has_many relation for only new records

How to create a new nested attribute form for only new records in a has_many relationship using simple_form, well according to this stackoverflow http://stackoverflow.com/questions/14884704/how-to-get-rails-build-and-fields-for-to-create-only-a-new-record-and-not-includ I was trying to create a new records using nested attributes the problem with that solution it is that if the form has error fields the form will be clear and boom after the page reloading you’ll have nothing filled in your form and can you imagine if you form is like 20 or 30 fields that would be a terrible user experience of course so let’s look at my solution using:

– Simple Form from plataformatec.
– Nested Attributes and has_many relationship
– Transactions in rails and rendering errors in form.
– Using service to create the data

Let’s take a closer look at the code:

Spree::User model

has_many :applications, -> { order("created_at DESC")}

has_one :new_application, class_name: 'Application'
accepts_nested_attributes_for :new_application

Code within the controller

def new
  @user = find_user
  @user.build_new_application
  respond_with @user
enda

def find_user
  spree_current_user || Spree::User.new
end

def create
  service = ServiceApplication.new(application_params, find_user)
  @user = service.perform

  if @user.valid?
    redirect_to root_path, notice: 'Your application is submitted'
  else
    render 'new'
  end
end

private

  def application_params
    params.require(:user).permit(
      :username,
      :password,
      :new_application_attributes => [
        :name,
      ]
    )
  end

app/services/application_service.rb

class ApplicationService

  def initialize(application_params, user)
    @application_params = application_params
    @current_user = user
  end

  def perform
    @current_user.transaction do
      begin
        create_application_and_user
      rescue => e
        Rails.logger.error "=========== exception creating application ===#{e.inspect}========"
        raise ActiveRecord::Rollback
      end
    end
    @current_user
  end

  def create_application_and_user
    @current_user.attributes = @application_params
    @current_user.save!
  end
end

app/views/applications/new.html.erb

<%= simple_form_for(@user, url: applications_path, method: :post, html: { novalidate: false}) do |f| %>

  <p>(*) Indicates required field</p>
  <%= render :partial => 'shared/error_messages', :locals => { :target => @user } %>

  <%= f.simple_fields_for :new_application do |ff|  %>
    <%= ff.input :name , label: 'Name:'%>
  <% end %>

  <%= f.input :username, required: true, label: 'Username:' %>
  <%= f.input :password, required: true, label: 'Password:' %>
<% end %>

That’s it I hope you learnt stuff, regards
H.

No Comments

Post A Comment