Rails "gotchas"Edit
This article is about Rails "gotchas": things that may be puzzling or confounding if you don’t know about them. Beware that this is a long-lived document and the behaviour in some or all of these "gotchas" might have changed since they were originally written.
Overlong text
fields get silently truncated when written to MySQL
If you use the text
type in your migrations, this will map to the TEXT
column type in your MySQL database, which has a limit of about 65535 bytes.
When you save a record with more than 65535 bytes in that attribute it will be silently truncated to that length and you won’t be given any warning. You will lose data.
The moral of the story is:
If you think (or care) that a user might submit more than 64KB of content for such an attribute, you should set up a validation so that they’ll be notified of the problem if they ever exceed the limit.
Adding more validations is adding more overhead and slowing you down, but it’s better than silently throwing away data.
The other lesson you might want to take home from this is that if you really do want to accept more than 64KB in your attributes then you’ll need to explicitly use the MEDIUMTEXT
column type. It’s MySQL-specific, but in any application of decent size you’ve probably already been forced down the path of using some MySQL-specific stuff anyway.
You’ll still want to use validations, of course, because the MEDIUMTEXT
column type allows you more space than you’d really want to make available (enough for it to be abused).
I’m writing about this "gotcha" because it’s something I ran into in January 2009 (surprised it took me that long). For more details see ticket #1190.
The cookies
hash is not actually a hash
[C]ookies
isn’t a Hash
, although the cookies
method does return a CookieJar
object, which extends Hash
. CookieJar
mangles the expected Hash
methods of []
and []=
with these gotchas:
- The
CookieJar
object does not represent one set of cookies, it represents 2 sets: the incoming cookies from the browser, and the outgoing cookies that will be sent back to the client
cookies[:key]
gets you the incoming cookies from the client
cookies[:key]=
value sets outgoing cookies that will be sent back to the client
- … all of which mean that
cookies[:its] = "1999"
will not allow you to retrieve that value with cookies[:its]
.
[C]ookies
isn’t a Hash
, although the cookies
method does return a CookieJar
object, which extends Hash
. CookieJar
mangles the expected Hash
methods of []
and []=
with these gotchas:
- The
CookieJar
object does not represent one set of cookies, it represents 2 sets: the incoming cookies from the browser, and the outgoing cookies that will be sent back to the client cookies[:key]
gets you the incoming cookies from the clientcookies[:key]=
value sets outgoing cookies that will be sent back to the client- … all of which mean that
cookies[:its] = "1999"
will not allow you to retrieve that value withcookies[:its]
.
Source: "Rails Cookies Mangles the Hash Interface", http://www.40withegg.com/2007/1/5/rails-cookies-mangles-the-hash-interface/
Beware of returning false
from a before_filter
See "before_filter" in Ruby on Rails.
Validation
Validation is quite a tricky subject. As an example see, "Validating passphrases with Ruby on Rails". In that article I describe the order in which :save
, :create
and :update
validations are applied (probably not the order you think it is), as well as note some of the tricky issues that can crop up validating virtual attributes.