如何使用DataMapper和Sinatra的复选框进行操作? [英] How do I work with checkboxes with DataMapper and Sinatra?
问题描述
我想做一个简单的房间管理服务。房间有这些属性:
I'm trying to make a simple room management service. The rooms have these properties:
class Room
include DataMapper::Resource
validates_is_unique :number
property :id, Serial
property :number, Integer
property :guest, String
property :status, Enum[ :free, :occupied ], :default => :free
end
然后我创建一个这样的新房间
Then I create a new room like this
post '/new' do
content_type :json
@room = Room.new :guest => params[:guest],
:number => params[:number],
:status => params[:status]
if @room.save
{ :number => @room.number, :guest => @room.guest, :status => @room.status }.to_json
end
end
%form#new_message{:action => '/new', :method => 'post'}
%p
%input{:type => "text", :id => "number", :name => "number"}
%input{:type => "text", :id => "guest", :name => "guest"}
%input{:type => "checkbox", :id => "status", :name => "status", :value => "occupied"}
%input{:type => "submit", :value => "post"}
当选中此框时:状态为已占用取消选中对象将不会保存。我认为它会工作,因为它默认为自由,但没有...
When the box is checked the :status is "occupied" but when I leave it unchecked the object won't save. I thought it would work since it is defaulted to "free" but no...
推荐答案
对于任何愚蠢的原因,如果未点击,则不会提交。这意味着他们不在你的应用程序的哈希。当你说:status => params [:status]
你真的说:status => nil。因为你设置了一个值,它会检查你的枚举,而nil不在你的枚举,所以它失败验证。 (根据你如何使用它,看起来不应该是一个布尔值称为占用或可用?)
For whatever stupid reason, checkboxes do not get submitted if they are not clicked. This means they are not in the hash that hits your app. When you say :status => params[:status]
you are really saying :status => nil. Since you have set a value, it checks that against your enum, and nil is not in your enum, so it fails validations. (based on how you are using this, doesn't it seem like it should be a boolean called either "occupied" or "available" ?)
无论如何,你可以显式地将其设置为自由,或者不设置它,并让默认值来处理它。这就是我选择检查时,通过移动到一个质量分配。我使用的代码如下。
Anyway, you could either explicitly set it to free, or not set it at all, and let the default take care of it. That is what I opted for when checking it, by moving it into a mass assignment. The code I used is below.
require 'rubygems'
require 'sinatra'
require 'haml'
require 'dm-core'
require 'dm-validations'
require 'dm-types'
require 'dm-migrations'
require 'sqlite3'
configure do
class Room
include DataMapper::Resource
validates_uniqueness_of :number
property :id, Serial
property :number, Integer
property :guest, String
property :status, Enum[ :free, :occupied ], :default => :free
end
set :sessions , true
DataMapper::Logger.new($stdout, :debug)
DataMapper.setup( :default , "sqlite3://#{Dir.pwd}/development.sqlite3" )
DataMapper.finalize
DataMapper.auto_upgrade!
end
get '/' do
@rooms = Room.all
haml :index
end
post '/new' do
p params
@room = Room.new params[:room]
if @room.save
session[:flash] = "room reserved"
redirect '/'
else
session[:flash] = @room.errors.to_a
redirect '/new'
end
end
get '/new' do
haml :new
end
__END__
@@layout
!!!
%html
#flash
= session[:flash].inspect
= yield
@@new
%form#new_message{:action => '/new', :method => 'post' , :name => 'room' }
%p
%input{:type => "text", :id => "number", :name => "room[number]"}
%input{:type => "text", :id => "guest", :name => "room[guest]"}
%input{:type => "checkbox", :id => "status", :name => "room[status]", :value => "occupied"}
%input{:type => "submit", :value => "post"}
@@index
%table
- @rooms.each do |room|
%tr
%td= room.number
%td= room.guest
%td= room.status
这篇关于如何使用DataMapper和Sinatra的复选框进行操作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!