Reputation: 851
My app has a portfolio that has many positions. Each position has many movements.
Within a portfolio I am showing all of my positions.
<p>
<strong>Name:</strong>
<%= @portfolio.name %>
</p>
<%= render partial: @positions %>
<%= render 'positions/form' %>
<%= link_to 'Edit', edit_portfolio_path(@portfolio) %> |
<%= link_to 'Back', portfolios_path %>
My position partial is written like this:
<ul>
<li><%= position.name %></li>
<li><%= position.quantity %></li>
<li><%= position.ticker %></li>
</ul>
<%= form_for [@portfolio, position, @movement] do |f| %>
<div id = "movement-errors">
<% if @movement.errors.any? %>
<%= render partial: 'movements/movement_error_messages' %>
<% end %>
</div>
<div class="field">
<%= f.label :quantity %>
<%= f.text_field :quantity %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
With my error partial like this:
<% if @movement.errors.any? %>
<div id = "error_explanation">
<div class = "alert alert-danger">
The form contains <%= pluralize(@movement.errors.count, "error") %>.
</div>
<ul>
<% @movement.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
When I submit an empty quantity I want the error message to render on the same page. As it stands right now, when I submit an empty form, I'm redirected to the Movements#new page where I have a form and it has an update button.
My Movement controller is built like:
class MovementsController < ApplicationController
before_action :load_portfolio_and_position
def create
@movement = Movement.new(movement_params)
@movement.position_id = @position.id
@movement.update_price
@movement.date = DateTime.now
@movement.trade ='buy'
respond_to do |format|
if @movement.save
@position.update_attribute(:quantity, (@movement.quantity + @position.quantity))
format.html { redirect_to @portfolio, notice: 'Movement was successfully created.' }
format.js
else
format.html { render :new }
format.json { render json: @movement.errors, status: :unprocessable_entity }
format.js
end
end
end
I just want to submit either valid or invalid data and have it be handled in the same page.
Upvotes: 0
Views: 1056
Reputation: 102443
Use local variables instead when building partials. This makes them truly reusable and useful:
# app/views/shared/_errors.html.erb
<% if object.errors.any? %>
<div id = "error_explanation">
<div class = "alert alert-danger">
The form contains <%= pluralize(object.errors.count, "error") %>.
</div>
<ul>
<% object.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
This means we can render it like:
<%= render 'shared/errors', object: @movement %>
I just want to submit either valid or invalid data and have it be handled in the same page.
Thats not how Rails works and for good reason. When you submit a form and the form is invalid you render a view which displays the error messages and form in so that the user can correct the issues.
Redirecting back would put any user entered data in the query string where it is less secure or rely on using the session in a way that violates REST.
format.html { render :new }
Does not call the new action in your controller. It just looks for a /movements/new.html.erb
view and renders it.
You can of course have it render any other view you want. Like render template: 'foo/bar'
.
Upvotes: 1