将Datamapper与Sinatra一起使用,保存文本属性非常简单:
DataMapper::setup(:default, "sqlite3://#{Dir.pwd}/tailor.db")
class Person
include DataMapper::Resource
property :id, Serial
property :name, String, :required => true
property :height, String, :required => false
end
DataMapper.finalize.auto_upgrade!
...
put '/:id/edit' do
p = Person.get params[:id]
p.name = params[:name]
p.height = params[:height]
p.save
end
Run Code Online (Sandbox Code Playgroud)
并且观点:
%form
%input{:type => 'text', :name => 'name'}
%input{:type => 'text', :name => 'height'}
%input{:type => 'submit', :value => 'Save'}
Run Code Online (Sandbox Code Playgroud)
随着:type => 'text'它是一件轻而易举的事.但是,我在尝试property :test, Boolean, :required => false使用复选框设置boolean()时遇到了麻烦.这个问题类似,但没有解决如何做一个简单的布尔值.
另外,设置不接受任何字符串的值的最简单方法是什么,而只是一组预定义的选项 - 作为允许一个选择的选择,还是允许多个选项的一组单选按钮?
编辑:
我想出了复选框:
p.bool = !params[:bool].nil?
Run Code Online (Sandbox Code Playgroud)
并在视图中:
%input{:type => 'checkbox', :name => 'bool', :value => "#{@bool}", :checked => @p.bool}
Run Code Online (Sandbox Code Playgroud)
当您提交带有a的表单时checkbox,如果您未指定value表单,则默认为字符串on.此外,如果未选中该复选框,则根本不会提交.因此,结果是在您的处理程序中params[:test](假设checkbox已命名test)是nil未选中的,或者是否为字符串on.
期望为Datamapper中的布尔属性分配布尔(true或false),或者它将隐式转换的一小组值中的一个.on并且nil不在这些值中,因此当您尝试将值分配给Datamapper时,它将无法通过验证而不能保存:
...
p.test = 'on'
if !p.save
p p.errors[:test]
end
Run Code Online (Sandbox Code Playgroud)
生产:
["Test must be of type TrueClass"]
Run Code Online (Sandbox Code Playgroud)
解决此问题的一种方法是检入处理程序并在分配给属性时将值显式转换为布尔值:
p.test = params[:test] == 'on' ? true : false
Run Code Online (Sandbox Code Playgroud)
另一种方法是value将HTML复选框设置为Datamapper将转换的值之一,以便您可以直接传递它.您可以在表单中使用多个具有相同名称的控件,它们将按照它们在页面中显示的顺序提交.Sinatra将仅在创建params哈希时使用最后一个,因此如果您添加hidden与复选框之前的复选框具有相同名称的输入,则如果未选中该值,则该值将是隐藏输入的值.如果选中它,它的值将覆盖隐藏输入的值.
%input{:type => 'hidden', :name => 'foo', :value => 'f'}
%input{:type => 'checkbox', :name => 'foo', :value => 't'}
Run Code Online (Sandbox Code Playgroud)
现在params[:test]将是'f'或者't',两者都是Datamapper将为您转换,所以您可以简单地做
p.test = params[:test]
Run Code Online (Sandbox Code Playgroud)