vendredi 17 juillet 2015

Ruby On Rails - creating an object does not respect validations and showing error messages

I'm having troubles handling objects that not respect the validation. I'm building an app in which an user can create a "Trip" model and then add steps to his trip, that I called "Traces". Each added trace prints a new part of a map present in the trip#show action. The association between models is user has_many trips and trip has_many traces

In the users#show I put a "CREATE NEW TRIP" button linking to the trips#new and here I have the form_for with the field corresponding to the Trip attributes. When I fill the form correctly everything is ok. When something is missing or wrong (for the validations) I get this error:

NoMethodError in Trips#create
undefined method `model_name' for Array:Class

I also have a similar problem with the creation of a new Trace:

The form for adding a new trace is in the trip#show page. When I try to create a trace that not respects the validation (e.g. if I leave blank the "destination" field) I get this error:

Template is missing 
Missing template shared/add_trace_form with {:locale=>[:en], :formats=>[:html], :handlers=>[:erb, :builder, :coffee]}. 
Searched in: * "/Users/francescocretti/RubymineProjects/traces/app/views" * "/Users/francescocretti/RubymineProjects/traces" * "/"

I know that these are two different problems, but I suppose I'm doing something wrong handling the error messages. I probably misunderstood something, even because I'm new to Rails and web programming in general.

Here you are some code parts, hoping it helps to understand my mistake:

------ in the trips_controller.rb

def create
  @trip = current_user.trips.build(params[:trip])
  if @trip.save
    # handle a successful save
    flash[:success] = 'Trip created!'
    redirect_to user_trip_path(@trip, user_id: current_user.id)
    else
    @trip = []
    @feed_items = []
    render 'new'
  end
end

------ in app/views/trip, in the new.html.erb

h1>Create a trip</h1>
<div class="row">
  <div class="col-md-6 col-md-offset-3 general-input">
    <%= form_for ([current_user, @trip]) do |f| %>

    <%= render 'shared/error_messages', object: f.object %>
    <%= f.label :name,'Give a name to your trip ;)' %>
    <%= f.text_field :name %>
    <%= f.label :trip_start, 'Choose your starting point!' %>
    <%= f.text_field :trip_start %>
    <%= f.label :departure, 'When are you leaving?' %>
    <%= f.date_select :departure, :start_year => Date.current.year   %>
    <%= f.label :arrive, 'And coming back home?' %>
    <%= f.date_select :arrive, :start_year => Date.current.year %>

    <%= f.submit 'Create a new trip', class: 'btn btn-primary btn-lg' %>
<% end %>

------ in the traces_controller.rb

def create
 @trip= Trip.find(params[:trip_id])
 @trace = @trip.traces.create(params[:trace])
  if @trace.save
   flash[:success] = 'Trace created!'
   redirect_to user_trip_path(@trip, user_id: current_user.id)
   else
   @trace=[]
   render 'shared/add_trace_form'
 end
end

------ in app/views/shared, in the add_trace_form.html.erb

<p>Complete your trip adding a route!</p>
 <%= form_for ([@trip, @trip.traces.build]) do |f| %>
  <%= render 'shared/error_messages', object: f.object %>
  <div class="block post-form">
  <div class="field ">
  <%= f.text_field :end, placeholder: 'Where are you going next?' %>
  <%= f.label :arr_day, 'When?' %>
  <%= f.date_select :arr_day, :start_year => Date.current.year   %>

  <%= f.submit 'Add route', class: 'btn btn-primary btn-landing' %>
   </div>
  </div>
<% end %>

------ in app/views/shared, in the error_messages.html.erb

 <% if object.errors.any? %>
    <div id="error_explanation">
    <div class="alert alert-error">
    The form contains <%= pluralize(object.errors.count, "error") %>.
    </div>
    <ul>
     <% object.errors.full_messages.each do |message| %>
        <li>* <%= message %></li>
    <% end %>
    </ul>
  </div>
<% end %>

------ in the routes.rb

resources :users do  
  resources :trips
end

resources :trips do
  resources :traces
end

resources :traces

Thanks a lot

Aucun commentaire:

Enregistrer un commentaire