Posts Tagged ‘rails’

Rails bug?

Friday, April 18th, 2008

I discovered what looks like a bug with has_many :finder_sql.  The docs claim that if you supply :finder_sql and not :counter_sql, it makes the counter by replacing “SELECT * FROM …” with “SELECT COUNT(*) FROM …”.

This does not appear to work if your :finder_sql has a subquery.  To make up a fake example:

class User
    has_many :comments_not_mine,
        :class_name => 'Comment',
        :finder_sql => 'SELECT * FROM comments WHERE user_id != "#{id}" AND EXISTS (SELECT * FROM users)'
end

(The EXISTS part is silly, and just there to show a subquery.)

Now I can say user.comments_not_mine and it works fine, but user.comments_not_mine.count gives an error about the SQL "SELECT COUNT(*) FROM users)". It appears to be using a greedy regexp by mistake. (user.comments_not_mine.to_a.size works fine. It’s just the #count method it adds is trying to be clever, and failing.)

For the life of me, I can’t find it, so: dear lazyweb, please find the offending regexp, so I can write a patch.

Fixed an evil bug; two things I learned

Monday, April 7th, 2008

1. link_to_remote’s :update parameter is the box to put the new object in, not the box to replace

2. If you stupidly have more than one element in your DOM with the same ID (see #1), and ask for it by ID, Firefox 2 takes the last one; Firefox 3, Safari, and Opera all take the first one.

Not knowing these facts can make debugging AJAX code in Rails seriously unfun.  It’s one thing when IE6 screws up your webpage, but when Firefox 2 doesn’t do what you want, it’s like it’s mocking you.

Things I learned about fixtures the hard way

Wednesday, February 27th, 2008

0. “rake db:fixtures:load” will empty your dev db and fill it with your fixture data. If you’re wondering what’s going wrong with your fixtures, this can be a huge help.

1. The AR fixtures code does not check to see if a record is valid before inserting it. And it only checks validity on save (mostly), so it’s quite possible to get an error in testing (but not dev) that’s due to an invalid fixture record.

If you can’t get something to work quite right, it may be due to a bad fixture, and your code and test may be correct.  Something as simple as an omitted field in a fixture you haven’t touched can be enough to ruin your whole afternoon.

2. Another thing that doesn’t check for validity is Foo.delete_all. This is a quick and easy way to kill referential integrity. It’s generally a bad idea in tests, even if you’re using transactional fixtures.

3. With new “foxy fixtures”, you can say “mission: foo” to hook mission_id to foo[:id], but this doesn’t work through a belongs_to link that uses :foreign_key. I mentioned it to somebody at seattle.rb who claims to work with Fixtures Guy, so maybe it’ll get fixed someday.

Foxy fixture links aren’t checked for validity, either, BTW. It just hashes the name you pass, so if you say “mission: bogus”, and there’s no mission fixture called “bogus”, it’ll still insert a value, and you’ll get a weird error. (Or worse, “mission: threee”.)

4. (Not related to fixtures at all) In Rails, “.” in a (URL) path is a “route separator“, so it doesn’t behave like you expect by default. The fix is to add something like:

:requirements => {:id => /[a-zA-Z0-9_@\.]+/}

to the map.connect call in routes.rb.