首先是环境:
Rails 2.1.0,Ruby 1.8.7,Mysql 5.1.54,Ubuntu 11.04
我的表中有一个布尔字段,它以NULL开头,但我找不到一个好方法设置它为NULL。 (这个字段基本上是一个是/否/未答复的字段,其中true / false / null似乎是正确的。客户明确表示他希望它能够保持为空(未答复)。)
这是我的迁移(替换了特定名称):
class AddQuestionToClients < ActiveRecord::Migration
def self.up
add_column :clients, :question, :boolean
end
def self.down
remove_column :clients, :question
end
end
我的控制器使用基本的
@client = Client.find(params[:id])
@client.update_attributes(params[:client])
我的观点有一个选择(我认为这导致了问题,对于表单助手选择从来都不是很好):
<%= f.select :question, [["Yes", true], ["No", false]], { :include_blank => true, :selected => @client.question } %>
选择yes时,会传递true;不,错误通过;空白,“”通过。 但是“”在更新数据库时似乎会自动转换为false。
为了解决这个问题,我正在这样做:
params[:client][:question] = (params[:client][:question] == "")? nil : params[:client][:question]
但这不是正确的做法。我错过了什么?
答案 0 :(得分:2)
我遇到了同样的问题,我通过将属性转换为空来解决了这个问题。在您的情况下,我会向您的模型类添加一个方法。
class Client < ActiveRecord::Base
def question=(value)
value = nil if value == ''
super(value)
end
end
这适用于创建和更新。 (我正在使用Rails 2.0.5。)
答案 1 :(得分:1)
<%= f.select :question, options_for_select([["Yes", true], ["No", false]], :question) %>
答案 2 :(得分:1)
我遇到了同样的问题,默认情况下我需要空值来表示“未回答”的布尔值
使用Rails 3.2,当我为布尔值(空白选项)传递“”时,在db中将列设置为NULL。
使用较新版本的rails解决了问题:)
答案 3 :(得分:0)
我认为你只能以服务器端的方式做到这一点,因为当发布数据时总是不是零。所以你的解决方案是正确的。
如果你想避免那些丑陋的代码,你可以使用javascript做一点技巧客户端。实际上,如果您使用禁用的元素而不是空白值,那么该值将不会发布,并且您在服务器端获得nil
。
为此,您可以添加一个提交回调,检查问题字段是否为空,如果是,则在发布数据之前将其禁用。这样它就可以在没有任何服务器端代码的情况下工作。
要使用jQuery禁用元素,您可以看到this link。因此,假设您的表单具有#form
ID,则可以使用此代码
$(function() {
$('#form').submit(function () {
if ($('question-selector').val() == "") {
$('question-selector').attr('disabled', true);
}
})
});
答案 4 :(得分:0)
@vdaubry我只会补充说它没有真正解决..因为你在UI中使用'select'而被屏蔽了。如果你愚蠢到使用复选框,像我一样(毕竟,它们是布尔值,对吗?)然后你在db中我们的意思是代表'未知'的漂亮的默认nil值被转换为'false'查看,并在db中转换为false,即使它未在视图中更新,与上面描述的相同。换句话说,继续依赖第三个值“布尔”是一致的,有点脆弱。
此外,如果曾报告此属性,则报告代码无法轻易推断出数据库中的值,如果“未知”是有效含义并且模糊不清。
所以我选择重构我的所有布尔值,使它们成为字符串('是','不','未知')并在视图中使用单选按钮。请注意,这仅适用于数据收集UI这样的事情,用户没有找到真相,因此从统计上来说,如果它是“未知”的话,它会很重要。
答案 5 :(得分:0)
以前的帖子中没有提到这一点,但在Rails 5中,如果你想命名nil选项,这应该可行
<%= f.select :question, [["Yes", true], ["No", false]], { :include_blank => 'Name this whatever you want, it will be nil when submitted', :selected => @client.question } %>
在我自己的项目上测试了这个