使用mysql的Rails/ActiveRecord BIT
我在使用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
可以覆盖属性读者您发布的属性:
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
但我认为第一个解决方案(覆盖属性读取器)更好。
继承人根据@ 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?
方法。
感谢您的帮助@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>
更新为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
我已经想过这样做,但它似乎不是一个好的解决方案。 – 2013-05-07 13:31:00
为什么不呢?你为什么不使用正常的布尔字段而不是位? – Mattherick 2013-05-07 13:32:43
更新了我的答案。 – Mattherick 2013-05-07 13:55:01