Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

default_scope breaks (update|delete|destroy)_all in some cases

I believe this is a bug in Rails 3. I am hoping someone here can steer me in the correct direction. The code posted below, is purely for illustration of this problem. Hopefully this does not confuse the issue.

Given I have a Post model, and a Comment model. Post has_many Comments, and Comment belongs_to Post.

With a default_scope set on the Post model, defining joins() and where() relations. In this case where() is dependent on joins().

Normally Posts wouldn't be dependent on Comments. Again, I just want to give a simple example. This could be any case when where() is dependent on joins().

class Post < ActiveRecord::Base
  has_many :comments, :dependent => :destroy

  default_scope joins(:comments).where("comments.id < 999")
end

class Comment < ActiveRecord::Base
  belongs_to :post, :counter_cache => true
end

Running the following command:

Post.update_all(:title => Time.now)

Produces the following query, and ultimately throws ActiveRecord::StatementInvalid:

UPDATE `posts` SET `title` = '2010-10-15 15:59:27'  WHERE (comments.id < 999)

Again, update_all, delete_all, destroy_all behave the same way. I discovered this behaviour when my application complained when trying to update the counter_cache. Which eventually drills down into update_all.

like image 591
releod Avatar asked Feb 04 '23 01:02

releod


1 Answers

I had this problem also, but we really needed to be able to use update_all with complex conditions in the default_scope (for example, without the default scope eager-loading is impossible, and pasting a named scope literally everywhere is no fun at all). I have opened a pull request here with my fix:

https://github.com/rails/rails/pull/8449

For delete_all I've raised an error if there's a join condition to make it more obvious what you have to do (instead of just tossing the join condition and running the delete_all on everything, you get an error).

Not sure what the rails guys are going to do with my pull request, but thought it was relevant to this discussion. (Also, if you need this bug fixed, you could try out my branch and post a comment on the pull request.)

like image 177
Derek Kraan Avatar answered Feb 05 '23 16:02

Derek Kraan