Reputation: 26272
I'm trying to redisplay a form without losing the data, after a validation failure.
Model:
class Book < Sequel::Model
plugin :validation_helpers
def validate
super
validates_presence [:title], message: 'Title is required'
end
end
create.erb
:
...
<%= erb :'partials/flash' %>
...
<form method="post" action="/books/create">
<input name="book[title]" type="text" value="<%= @book.title %>" />
<textarea name="book[description]"><%= @book.description%></textarea>
...
</form>
...
flash.erb
:
<% flash.map do |f| %>
<div class="alert alert-<%= f[0] %> alert-dismissible fade show" role="alert">
<%= f[1] %>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<% end %>
BooksController
:
# display a table of books
get '/' do
@books = Book.all
erb :'books/index'
end
# display CREATE form
get '/create' do
@book = Book.new
erb :'books/create'
end
# process CREATE form
post '/create' do
begin
@book = Book.create(params[:book])
flash[:success] = "Book created."
redirect to("/") # /books/
rescue Sequel::ValidationFailed => e
flash[:danger] = @book.errors
redirect to "/create" # redisplay the form
end
end
While this works, the data that was entered in the form is lost.
What is the recommended way to redisplay the form with its latest entries?
** edit ** added flash template
Upvotes: 0
Views: 105
Reputation: 11807
@book.errors
object instance.Upvotes: 1
Reputation: 26272
For the sake of completeness, the final code:
Controller:
post '/create' do
begin
@book = Book.new(params[:book])
@book.save
flash[:success] = "Book created."
redirect to("/")
rescue Sequel::ValidationFailed => e
erb :'books/create'
rescue => e
flash[:danger] = e.message
erb :'books/create'
end
end
Form (using Bootstrap):
<form method="post" action="/books/create">
<div class="form-group">
<label for="inputTitle">Title</label>
<input id="inputTitle" name="book[title]" type="text" class="form-control <%= 'is-invalid' if @book.errors[:title] %>" placeholder="Title" value="<%= @book.title %>">
<%= erb :'partials/validation_errors', locals: {field: :title, errors: @book.errors} %>
</div>
...
</form>
validation_errors.erb
:
<% if locals[:errors].has_key?(locals[:field]) %>
<div class="invalid-feedback">
<ul>
<% locals[:errors][locals[:field]].each do |error| %>
<li><%= error %></li>
<% end %>
</ul>
</div>
<% end %>
Upvotes: 0