So this is a simple project where there are products and you can bid for them. Think eBay.
I built the project as follows:
$ rails new routetest
$ rails g scaffold product productname reserveprice:integer
$ rails g scaffold bid bidprice:integer product_id
On the 'show' view for each product I include
- the product details (as generated by the scaffold)
- a list of bids so far
- a form to sumbit new bids using the form_for helper
<p id="notice"><%= notice %></p>
<h2>Normal Products\Show Part</h2>
<p>
<strong>Productname:</strong>
<%= @product.productname %>
</p>
<p>
<strong>Reserveprice:</strong>
<%= @product.reserveprice %>
</p>
<%= link_to 'Back', products_path %>
<br /><br />
<h2>List of bids</h2>
<table>
<thead>
<tr>
<th>Product ID</th>
<th>Bid Price</th>
</tr>
</thead>
<tbody>
<% @bids.each do |bid| %>
<tr>
<td><%= bid.product_id %></td>
<td><%= bid.bidprice %></td>
</tr>
<% end %>
</tbody>
</table>
<br /><br />
<h2>Form For Bids</h2>
<h4>Make a Bid</h4>
<%= form_for(@bid) do |b| %>
<div class="field">
<%= b.number_field :bidprice %>
</div>
<div>
<%= b.hidden_field :product_id, :value => (params[:id]) %>
</div>
<div class="actions">
<%= b.submit %>
</div>
<% end %>
On clicking 'submit' the bids controller#create action is called.
def create
@bid = Bid.new(bid_params)
if @bid.save
redirect_to "/products/#{@bid.product_id}", notice: 'Bid was successfully created.'
else
render action: 'new'
end
end
So a sucessful bid returns the user to the product show view and adds the record to the bids section of the page.
I have a validates_presence_of validation in the bids model. So if the user leaves the bids field empty the validation fails and the bids controller crate action renders the bids new view. Including the error messages. The bids new view includes the scaffold generated code "<% if @bid.errors.any? %> etc"
What I actually want to do instead of rendering the new action is to throw the user back to the products show page as it does when a successful bid is made only to show the error messages on the products show page. Basically this gives the user the sense of staying on the products show page instead of throwing them to the bids new page.
The problem I have is how do I get the error message to pass back to the products show page? If I edit the bids controller create action code above and replace the "render action: 'new'" line with
redirect_to "/products/#{@bid.product_id}"
then the user is returned to the page but the error message isn't passed. I think this is because the error message is stored as part of the rendering of the new action (of the bids controller)
So my question is how do I achieve what I want to do? To return to the products show view and show the error messages that come from the failed validation. Thank you.
PS - I kow I need to add the scaffold generated code "<% if @bid.errors.any? %> ..." code to the products show view but I haven't done so in the code above because it will cause a NilMethod error because the error isnt created for the method to exist on it.