Rails选择具有NULL值的布尔值

时间:2011-08-15 23:48:50

标签: ruby-on-rails select null

首先是环境:

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]

但这不是正确的做法。我错过了什么?

6 个答案:

答案 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 } %>

在我自己的项目上测试了这个