Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #226 (closed defect: fixed)

Opened 4 years ago

Last modified 2 years ago

Alan

Reported by: dsalama Assigned to: David
Priority: normal Milestone: 0.9.5
Component: ActiveRecord Version: 0.8
Severity: normal Keywords:
Cc:

Description

MySQL stores boolean values in tinyint(1) column definition. Even though you can always "refer" to them as type boolean (since it's only an alias), when AR does a SHOW FIELDS in order to "guess" the column types, it expects to read boolean.

By modifying ActiveRecord::ConnectionAdapters:Column#simplified_type in active_record/lib/connection_adapters/abstract_adapter.rb to read like this:

def simplified_type(field_type)

case field_type

when /boolean/i, /tinyint\(1\)/i

:boolean

when /int/i

:integer

when /float|double|decimal|numeric/i

:float

when /time/i

:datetime

when /date/i

:date

when /(c|b)lob/i, /text/i

:text

when /char/i, /string/i

:string

end

end

the problem is fixed

Attachments

mysql_boolean.patch (1.6 kB) - added by Gerardo Malazdrewicz <fname@lname.com.ar> on 03/26/05 20:51:33.
Recognize tinyint(1) as a proper boolean type

Change History

03/01/05 07:01:16 changed by nzkoz

  • status changed from new to closed.
  • resolution set to worksforme.

This works for me now, if you have a column (blah) of type tinyint(1) you can reference it like this:

obj.blah? #-> true obj.blah=false

03/26/05 20:51:33 changed by Gerardo Malazdrewicz <fname@lname.com.ar>

  • attachment mysql_boolean.patch added.

Recognize tinyint(1) as a proper boolean type

03/26/05 21:01:31 changed by Gerardo Malazdrewicz <fname@lname.com.ar>

  • status changed from closed to reopened.
  • resolution deleted.

Using AR 1.9.0, found this change insufficient, as the proper value wasn't put back in the DB, so I modified also the type_cast and quote functions.

Done at the Mysql adapter level. It treats any tinyint(1) as boolean.

03/27/05 06:53:06 changed by ulysses

  • status changed from reopened to closed.
  • resolution set to worksforme.

I can't produce any issues. Please elaborate as to the error. What is the improper value? What would the proper value be? Use snippets of the code controlling the model, and pieces of the sql log as evidence. For extra marks, submit a test case which illustrates the error. (It must fail, obviously.)

03/29/05 13:30:15 changed by Miles Barr <miles@milesbarr.com>

I've had problems with bool (TINYINT(1)) and MySQL too. Basically ActiveRecord won't translate 'obj.blah = true' into '1' in the database. I can't remember exactly what it does, but I think it tries to set it to the string 'true' and fails, and the value in the database doesn't get changed. Up to now I've been using explicit '1' and '0' values in my Ruby code to get around this.

I'll put together a test case that demonstrates this and post it here when I'm done.

03/30/05 04:19:31 changed by Gerardo Malazdrewicz <fname@lname.com.ar>

What I'm doing is defining the tinyint(1) as the boolean of mysql, so listings show true and false by default, instead of whatever value and 0, respectively. Seems better to me than doing it at application level, maybe with a (non implemented) model option which allows to declare any integer field as a boolean, instead of mandatory on tinyint(1).

07/19/05 05:48:54 changed by lathiat@bur.st

  • status changed from closed to reopened.
  • resolution deleted.

This is still broken in the current release, scaffolding fails to recognise it as boolean so i assume its not working.

the attached patch while fixing the display issues, does not actually work for setting values etc as mentioned by the others.

Essentially, booleans in mysql are totally non operational. There is some code in the mysql activerecord adapter for tinyint(1) being boolean but nothing seems to recognise this,.

07/19/05 06:14:57 changed by nzkoz

  • status changed from reopened to closed.
  • resolution set to fixed.

You're referring to a different problem here, scaffolding not recognising booleans. Could you please open another ticket for it

@object.property?

will work

07/19/05 10:08:54 changed by lathiat@bur.st

ahh ok my mistake, sorry :)

06/09/06 19:01:00 changed by anonymous

  • status changed from closed to reopened.
  • resolution deleted.

I think this is problematic. Working with a legacy database, a column may be specified as TINYINT but not be used for boolean types(i.e. it may store more than two distinct values)

There should be a way to disable this in a model

06/09/06 21:06:14 changed by anonymous

  • status changed from reopened to closed.
  • resolution set to fixed.

ahh never mind, I found *_before_type_cast ... just took a little while. sorry for the trouble

06/10/06 01:34:29 changed by minam

Also, note that the width field is only used for display in mysql--it does not affect the actual storage size of the data. Thus, tinyint(2) would be interpreted as an integer, while tinyint(1) would be interpreted as a boolean.

In general, it is probably not worth differentiating between integer and tinyint for integer uses, disk storage capacity being what it is these days. However, using tinyint(2) is, I think, an acceptible workaround.

09/01/06 22:59:23 changed by Alan

  • severity changed from normal to 1.
  • cc set to Alan.
  • component changed from ActiveRecord to 1.
  • summary changed from Proper recognition of boolean columns in MySQL and ActiveRecord to Alan.
  • priority changed from normal to 1.
  • version changed from 0.8 to 1.
  • milestone changed from 0.9 to 1.
  • keywords set to Alan.
  • type changed from defect to 1.

Good design! <a href="http://yzpgwwxm.com/jfgr/kqwh.html">My homepage</a> | <a href="http://ecklvtqu.com/iaro/zrwv.html">Please visit</a>

09/01/06 23:41:24 changed by bitsweat

  • severity changed from 1 to normal.
  • cc deleted.
  • component changed from 1 to ActiveRecord.
  • priority changed from 1 to normal.
  • version changed from 1 to 0.8.
  • milestone changed from 1 to 0.9.5.
  • keywords deleted.
  • type changed from 1 to defect.