The latest version of Rails introduces the convenience method “first”
in ActiveRecord, which acts as find(:first). This is breaking my
application wherever the following type of interaction takes place:
blog.posts.first.title = “New title”
blog.save
When blog.save is called, an after_update hook will try to save the
associated posts. But since the line “blog.posts.first” loads a fresh
set of posts from the DB – instead of accessing the in-memory cache
as in previous versions of Rails – the change will not be saved.
The workaround is to say blog.posts[0] instead.
I find this quite insidious, and I’m just curious whether other people
have encountered the same problem, and do you consider this a poor API
change on Rails’ part?
Eric
i personally would never work that far down an object graph, instead i
would do
post = blog.posts.first
post.update_attribute :title, ‘new title’
I would’ve thought #first would’ve been a the #first method from Array.
What do you mean by latest version? Edge or 2.1?
On 21 Jul 2008, at 22:54, Ryan B. wrote:
I would’ve thought #first would’ve been a the #first method from
Array.
What do you mean by latest version? Edge or 2.1?
2.1 adds this. It’s because of the (usually helpful) feature whereby
class methods magically exist on associations
(so if you’ve got
class Post
def self.foo
end
end
then you get blog.posts.foo for free)
I was wondering whether that would cause trouble, although in my mind
I was mostly worrying about unneeded trips to the database.
Fred
In my case, it did cause association to be loaded when I expect it not
to. However, I agree I should have never worked that deep in the
association anyways. I guess it’s just another thing to look out for
in Rails.
On Jul 21, 4:00 pm, Frederick C. [email protected]
On 21 Jul 2008, at 23:41, Frederick C. wrote:
class methods magically exist on associations
I should read the source before I post. foos.first will generate a
find first in some circumstances.
In others (most notably if the association is already loaded) it just
calls first on the already loaded array.
Still there’s definitely potential for errors there.
I would have thought (and my experiments seem to confirm) that you’re
fine with
something.foos.something_that_causes_them_to_be_loaded
something.foos.first
the opposite will cause problems though
Fred