Rails / ActiveRecord working with mysql BIT
rails generate model references
enumerations rails
rails enum labels
rails attr_accessor enum
rails 3.2 enum
rails timestamps
rails global enum
I'm having problems working with a mysql bit in Rails and ActiveRecord. We store a bit for the published-state of Localities.
`published` bit(1) NOT NULL
I scaffolded it as published:binary
in rails.
Locality.first.published
returns "\x01"
.
How do I get rails to treat this field as a boolean?
There is a staled Ticket but hacking ActiveRecord is not really an option. https://rails.lighthouseapp.com/projects/8994/tickets/6102-activerecord-boolean-support-with-bit1-mysql-data-type
You can overwrite the attribute reader of your published attribute:
class Locality < ActiveRecord::Base # overwrite the attribute reader of the published attribute def published self.read_attribute(:published) == "\x01" ? true : false end end
UPDATE
Or generate a method for your boolean return value
class Locality < ActiveRecord::Base def to_boolean self.published == "\x01" ? true : false end end
So you can call:
Locality.first.published.to_boolean => true || false
But I think the first solution (overwriting attribute reader) is better.
fixtures with mysql bit(1) columns fail to load · Issue #18172 · rails , GitHub is home to over 40 million developers working together to host binary data in MySQL, and Binary in Active Record is represented as a MySQL and PostgreSQL. Running the following commands will work as expected: bundle exec rails db:migrate bundle exec rails db:rollback We will get a column on the database that will only accept the declared values. That's the same constraint we have on our Rails app, yay!
Thank you for your help @Mattherick.
With your help I have built something easier:
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
The highlight
is the name of the field stored as BIT
on database. And this solution also works with checkbox
on view without the need of changes:
<div class="field"> <%= f.label :highlight %> <%= f.check_box :highlight %> </div>
ActiveRecord Mysql2 incorrectly casting boolean values · Issue , MysqlAdapter and Mysql2Adapter are inconsistent in this respect. As mysql does not have a dedicated boolean type it's either 0 / 1 (tinyint) or t / f ( Learn more about how to use different primary key in rails with mysql.
Update for Rails 5: the new attributes API is made for handling situations just like this. First you define a subclass of ActiveRecord::Type::Value
that handles deserialize
ing from bit to boolean, and cast
ing back from boolean to bit:
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
Then you define the attribute on your model with the attribute
helper:
class MyModel < ApplicationRecord attribute :published, Values::BitBoolean.new end
Enums with Rails & ActiveRecord: an improved way, ActiveRecord Enums are a really good tool to use when you need that certain model's bundle exec rails g migration AddStatusToPosts We are using MySQL's enum() type to declare the possible values that the status column should have. Running the following commands will work as expected: Active Record is the ORM layer supplied with Rails. Active Record relieves us of the hassles of dealing with the underlying database, leaving us free to work on business logic. ActiveRecord relies on convention over configuration. Wherever possible, ActiveRecord guesses the correct configuration by reflecting against the data schema.
Heres an extension method based on @Mattherick's answer above:
lib/extensions/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)
and require in an initializer:
config/initializers/extensions.rb
require File.join(Rails.root, 'lib/extensions/active_record/bit_boolean.rb')
Which then can be used:
class Locality < ActiveRecord::Base alias_bit_to_boolean :published end
This will produce a locality.published?
method.
#6102 ActiveRecord: boolean support with bit(1) MySQL data type , BIT MySQL data type was added in MySQL 5.0.3 for MyISAM, and extended in 5.0.5 ruby: 1.8.7 gem mysql: 2.8.1 mysql server: 5.0.41. Problem. Activerecord#column_name? return false instead of true when using datatype Hi, Using mysql2 gem and activerecord, some queries fail. I may have troubles with my MySQL (misencoded values, double utf-8 encode, etc) but I don't know where is the problem. Here is the stac
Migrations, Active Record will work out which migrations should be run. t.boolean :receive_newsletter , :default => false If the database does not support this (for example MySQL) then when a migration fails the parts of it that succeeded will not be Active Record – Object-relational mapping in Rails ¶ ↑ Active Record connects classes to relational database tables to establish an almost zero-configuration persistence layer for applications. The library provides a base class that, when subclassed, sets up a mapping between the new class and an existing table in the database.
Configuring Rails Applications, By default, Rails assumes that primary key columns are are multiple developers working on the same application. config.active_record.maintain_test_schema is a boolean value which controls whether Active Record will consider all tinyint(1) columns in a MySQL database to ActiveRecord is the ORM that comes out-of-the-box with Rails. ActiveRecord (or AR) attempts to follow the Active Record design pattern . It plays the role of Model in the MVC architecture employed
Rails ActiveRecord with Database Column Defaults, I commonly set a default on my boolean columns when I'm defining a new migration. I do this primarily to minimize the potential for three states— Pro Active Record helps you take advantage of the full power of your database engine from within your Ruby programs and Rails applications. ActiveRecord, part of the magic that makes the Rails framework so powerful and easy to use, is the model element of Rails model/view/controller framework.
Comments
- I have already thought about doing it that way, but it does not seem like a good solution.
- and why not? why are you not using a normal boolean field instead of the bit?
- I would have used a boolean instead of a bit but I think it would break some legacy applications that are still in use. I just hoped to find a way around the comparison with "\x01" which could break sometime in the future.
- well I understand. If you only want to work around the "\x01" I think the easiest way is to overwrite the attribute reader. Otherwise you´ll maybe have to change a lot of code overall your application, if the "\x01" will change to a normal boolean sometimes..