如何使用DataMapper和Sinatra的复选框?

时间:2010-07-04 22:08:36

标签: ruby checkbox sinatra haml datamapper

我正在努力做一个简单的房间管理服务。房间有这些属性:

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

然后我创建了一个像这样的新房间

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

通过这个haml表单

%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"}

选中此框时:状态为“已占用”,但是当我取消选中该对象时,该对象将无法保存。我认为它会起作用,因为它被默认为“自由”但没有......

2 个答案:

答案 0 :(得分:2)

出于任何愚蠢的原因,如果未单击复选框,则不会提交复选框。这意味着它们不会出现在您的应用程序中的哈希值。当你说:status => params[:status]时你真的在说:status =>零。由于您设置了一个值,它会根据您的枚举进行检查,并且nil不在您的枚举中,因此验证失败。 (根据你如何使用它,看起来它应该是一个名为“被占用”或“可用”的布尔值?)

无论如何,您可以明确地将其设置为空闲,或者根本不设置它,并让默认设置处理它。这是我在检查时选择的,将其移动到批量分配中。我使用的代码如下。

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

答案 1 :(得分:0)

查看网络表单的HTML源代码!应该有一个隐藏字段,将未选中的复选框设置为默认值,以防无人检查...

另见:     http://railscasts.com/episodes/17-habtm-checkboxes?autoplay=true(到最后)