Rails 3 migrations: boolean (mysql vs postgreSQL)

2019-06-23 17:33发布

I'm trying to add a "sticky" option on my forum topics. This is how my migration looks like

  def self.up
    add_column :topics, :sticky, :boolean, :null => false, :default => false
  end

  def self.down
    remove_column :topics, :sticky
  end

This works perfect locally on mysql, but when I push the changes to heroku (which uses PostgreSQL), this is what I get when using the console

>> t.sticky
=> "f"
>> t.sticky.class
=> String
>> t.sticky = true
=> true
>> t.sticky.class
=> TrueClass

Why is the default value of this property a String?

Edit: And if I save the object, it doesn't change the sticky property, i.e. it's still "f".

3条回答
We Are One
2楼-- · 2019-06-23 17:39

Unless you find a bug in RoR or the database driver, as suggested by Denis, you may define (override) the read accessor as:

def sticky
  ! [false, nil, 'f'].include?( self[:sticky] )
end

This will convert known 'false' values to real ruby booleans.

I recall there were at least two gems to connect to PostgreSQL databases. Maybe you can use the other one?

And are you sure that the column in the database is not defined as String? I know that in your migration it's boolean, but maybe something somewhere went wrong?

查看更多
Emotional °昔
3楼-- · 2019-06-23 17:51

In psql, booleans are displayed as t or f. Depending on the DB driver, these get converted to booleans or left in their string representation.

The PDO driver in PHP does the same thing. (Or used to, anyway... I vaguely recall it no longer does in its latest version.)

查看更多
混吃等死
4楼-- · 2019-06-23 17:55

I'm not sure what the problem was, but I just rolled back the migration and ran it again, and it worked this time. Just putting this here in case someone else encounters a similar problem.

Thanks for your help guys.

查看更多
登录 后发表回答