4

Rails 4.2.1 using mysql2 gem. ActiveRecord treats a mysql column with data type tinyint(1) as a boolean. But I want to use it as a small number - I want to store values up to 100 which is ok for tinyint(1). When I try to create a record, the tinyint column casts to false and I get a depreciation warning:

> Foo.create(my_tinyint_col: 13)
  (0.2ms)  BEGIN
    SQL (0.5ms)  INSERT INTO `foos` (`my_tinyint_col`) VALUES (0)
  (107.3ms)  COMMIT
  => #<Foo ID: 519, my_tinyint_col: false> 

DEPRECATION WARNING: You attempted to assign a value which is not explicitly true or false to a boolean column. Currently this value casts to false. This will change to match Ruby's semantics, and will cast to true in Rails 5. If you would like to maintain the current behavior, you should explicitly handle the values you would like cast to false.

If i change the data definition of my_tinyint_col to tinyint(2) the problem goes away - but is there a way to treat tinyint(1) as a number using ActiveRecord?

joshweir
  • 5,427
  • 3
  • 39
  • 59

2 Answers2

4

Same issue occurs when tinyint(1) is seen as boolean by Hibernate. The trick is not to use tinyint(1) but to use tinyint(4). Doing so, RoR won't assume that it is boolean.

At any rate, there is actually no difference between tinyint(1) and tinyint(2) in MySQL. Both can hold the same values - 1 and 2 are signifiers of column width only.

See this please

Martin Samson
  • 3,970
  • 21
  • 25
MontyPython
  • 2,906
  • 11
  • 37
  • 58
2

For people who found this issue via google search: if you have the same problem but don't want to actually change the column data type you can add this line to your model.

attribute :my_tinyint_col, ActiveRecord::Type::Integer.new

Further reading: https://api.rubyonrails.org/classes/ActiveRecord/Attributes/ClassMethods.html

Adam
  • 518
  • 7
  • 17
  • Thanks. After looking at those docs I've just tried `attribute :my_tinyint_col, :integer` and it works! – Wodin Mar 29 '22 at 06:53