Ruby on rails Rails/ActiveRecord使用mysql位
我在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::
`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