Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails Rails/ActiveRecord使用mysql位_Ruby On Rails_Ruby On Rails 3 - Fatal编程技术网

Ruby on rails Rails/ActiveRecord使用mysql位

Ruby on rails Rails/ActiveRecord使用mysql位,ruby-on-rails,ruby-on-rails-3,Ruby On Rails,Ruby On Rails 3,我在Rails和ActiveRecord中使用mysql时遇到问题。 我们为地方的已发布状态存储了一点 `published` bit(1) NOT NULL 我在rails中将其构建为published:binary Locality.first.published返回“\x01” 如何让rails将此字段视为布尔值 有一张过期的票证,但入侵ActiveRecord并不是一个真正的选项。 您可以覆盖已发布属性的属性读取器: class Locality < ActiveRecord::

我在Rails和ActiveRecord中使用mysql时遇到问题。 我们为地方的已发布状态存储了一点

`published` bit(1) NOT NULL
我在rails中将其构建为
published:binary

Locality.first.published
返回
“\x01”

如何让rails将此字段视为布尔值

有一张过期的票证,但入侵ActiveRecord并不是一个真正的选项。

您可以覆盖已发布属性的属性读取器:

class Locality < ActiveRecord::Base
  # overwrite the attribute reader of the published attribute
  def published
    self.read_attribute(:published) == "\x01" ? true : false 
  end
end

但我认为第一种解决方案(覆盖属性读取器)更好。

这里有一种扩展方法,它基于@Mattherick的上述答案:

lib/extensions/active_record/bit_boolean.rb

并在初始值设定项中要求:

config/initializers/extensions.rb

然后可以使用:

class Locality < ActiveRecord::Base
  alias_bit_to_boolean :published
end
类位置

这将生成一个
locality.published?
方法。

感谢您的帮助@Mattherick

在你的帮助下,我做了一些更简单的事情:

  def highlight
    self.read_attribute(:highlight) == "\x01" ? true : false
  end

  def highlight=(value)
    content_value = (value == false || value == 0 || value == "0") ? "\x00" : "\x01"
    self.write_attribute(:highlight,content_value)
  end
突出显示的
是数据库中存储为
位的字段的名称。此解决方案还可以在视图中使用
复选框
,无需更改:

  <div class="field">
    <%= f.label :highlight %>
    <%= f.check_box :highlight %>
  </div>

Rails 5的更新:新的attributes API用于处理类似的情况。首先定义
ActiveRecord::Type::Value的子类
处理
反序列化
从位转换为布尔值,以及
从布尔值转换回位:

module Values
  class BitBoolean < ActiveRecord::Type::Value
    BIT_FALSE = "\x00"
    BIT_TRUE = "\x01"

    def cast(value)
      value ? BIT_TRUE : BIT_FALSE
    end

    def deserialize(value)
      value == BIT_TRUE
    end
  end
end

我已经想过这样做,但这似乎不是一个好的解决办法。为什么不呢?为什么不使用普通的布尔字段而不是位?我本来会使用布尔字段而不是位,但我认为这会破坏一些仍在使用的遗留应用程序。我只是希望能找到一种方法,绕过与“\x01”的比较,这种比较在将来某个时候可能会中断。我很理解。如果您只想处理“\x01”,我认为最简单的方法是覆盖属性读取器。否则,如果“\x01”有时会更改为普通布尔值,则可能需要在整个应用程序中更改大量代码。。
class Locality < ActiveRecord::Base
  alias_bit_to_boolean :published
end
  def highlight
    self.read_attribute(:highlight) == "\x01" ? true : false
  end

  def highlight=(value)
    content_value = (value == false || value == 0 || value == "0") ? "\x00" : "\x01"
    self.write_attribute(:highlight,content_value)
  end
  <div class="field">
    <%= f.label :highlight %>
    <%= f.check_box :highlight %>
  </div>
module Values
  class BitBoolean < ActiveRecord::Type::Value
    BIT_FALSE = "\x00"
    BIT_TRUE = "\x01"

    def cast(value)
      value ? BIT_TRUE : BIT_FALSE
    end

    def deserialize(value)
      value == BIT_TRUE
    end
  end
end
class MyModel < ApplicationRecord
  attribute :published, Values::BitBoolean.new
end