在不丢失数据的情况下重新显示 Sinatra 应用程序中的表单
Redisplay a form in a Sinatra application without loosing the data
我正在尝试在验证失败后重新显示表单而不丢失数据。
型号:
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
虽然这有效,但在表单中输入的数据丢失了。
使用最新条目重新显示表单的推荐方法是什么?
** 编辑 **
添加了 Flash 模板
- 不是在 post 救援部分中重定向,而是再次呈现创建表单模板,这将访问书籍实例和与之相关的错误
- 在表单渲染后使用 books 实例显示创建表单模板中的错误如果你想使用 flash 那么你需要从
@book.errors
对象实例中获取错误消息或提取消息。
为了完整起见,最终代码:
控制器:
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
表格(使用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 %>
我正在尝试在验证失败后重新显示表单而不丢失数据。
型号:
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
虽然这有效,但在表单中输入的数据丢失了。
使用最新条目重新显示表单的推荐方法是什么?
** 编辑 ** 添加了 Flash 模板
- 不是在 post 救援部分中重定向,而是再次呈现创建表单模板,这将访问书籍实例和与之相关的错误
- 在表单渲染后使用 books 实例显示创建表单模板中的错误如果你想使用 flash 那么你需要从
@book.errors
对象实例中获取错误消息或提取消息。
为了完整起见,最终代码:
控制器:
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
表格(使用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 %>