Search code examples
rubysinatrasequel

Redisplay a form in a Sinatra application without losing the data


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">&times;</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


Solution

    • Instead of redirecting in post rescue section render the create form template again which would access the books instance and errors associated with it
    • After form render use books instance to show errors in create form template if you want to use flash then you need to get the error message or extract messages from @book.errors object instance.