2013-05-07 95 views
5

我在使用Rails和ActiveRecord中的mysql位时遇到问题。 我们存储了一些地方发布的状态。使用mysql的Rails/ActiveRecord BIT

`published` bit(1) NOT NULL 

我把它作为published:binary脚手架在rails中。

Locality.first.published返回"\x01"

如何获得rails将该字段视为布尔值?

有一个staled票,但黑客ActiveRecord不是一个真正的选择。 https://rails.lighthouseapp.com/projects/8994/tickets/6102-activerecord-boolean-support-with-bit1-mysql-data-type

回答

5

可以覆盖属性读者您发布的属性:

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

UPDATE

或产生的方法为您的布尔返回值

class Locality < ActiveRecord::Base 
    def to_boolean 
    self.published == "\x01" ? true : false 
    end 
end 

所以,你可以电话:

Locality.first.published.to_boolean => true || false 

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

+0

我已经想过这样做,但它似乎不是一个好的解决方案。 – 2013-05-07 13:31:00

+0

为什么不呢?你为什么不使用正常的布尔字段而不是位? – Mattherick 2013-05-07 13:32:43

+0

更新了我的答案。 – Mattherick 2013-05-07 13:55:01

0

继承人根据@ Mattherick的回答上面的扩展方法:

的lib /扩展/ active_record/bit_boolean.rb

module Extensions::ActiveRecord 
    module BitBoolean 
    extend ActiveSupport::Concern 

    class_methods do 
     def alias_bit_to_boolean(attribute) 
     define_method("#{attribute}?") do 
      self.send(attribute) == "\x01" ? true : false 
     end 
     end 
    end 

    end 
end 

ActiveRecord::Base.send(:include, Extensions::ActiveRecord::BitBoolean) 

,并在初始化要求:

配置/ initializers/extensions.rb

require File.join(Rails.root, 'lib/extensions/active_record/bit_boolean.rb') 

其然后可用于:

class Locality < ActiveRecord::Base 
    alias_bit_to_boolean :published 
end 

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

0

感谢您的帮助@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 

highlight存储为BIT在数据库中的字段的名称。而这个解决方案还与checkbox适用于视图,而不需要改变的:

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

更新为Rails 5:新属性的API来处理,就像这样的情况下取得。首先定义的ActiveRecord::Type::Value 处理来自位deserialize ING为布尔值,并cast一个子类从布尔荷兰国际集团回位:

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 

然后定义与attribute帮助你的模型属性:

class MyModel < ApplicationRecord 
    attribute :published, Values::BitBoolean.new 
end