Rails 3.1, has_many relationship and new records problem

Supose I have a simple has_many relationship betwen model_1 and model_2:

class Model1 < ActiveRecord::Base     has_many :models_2 end

class Model2 < ActiveRecord::Base     belongs_to :model_1 end

Now, I create an instance of Model2 through the relationship:

m1 = Model1.first m2 = m1.models_2.new

Now, if I want to ask for the size of the relationship, there's a huge difference between Rails 3.0.x and Rails 3.1.

Following the previous example, in Rails 3.0.x i get:

m1.models_2.any? false m1.models_2.size 0

This means, new objects are not being considered

This exact same query in Rails 3.1:

m1.models_2.any? true #OMG!! m1.models_2.size 1

So, the solution is:

m1.models_2.all.any? false m1.models_2.all.size 0

If I have to change ALL my relationships with .all, I'm in a big trouble... am I missing something? Thank you very much.

Supose I have a simple has_many relationship betwen model_1 and model_2:

class Model1 < ActiveRecord::Base has_many :models_2 end

class Model2 < ActiveRecord::Base belongs_to :model_1 end

Now, I create an instance of Model2 through the relationship:

>m1 = Model1.first >m2 = m1.models_2.new

Now, if I want to ask for the size of the relationship, there's a huge difference between Rails 3.0.x and Rails 3.1.

Following the previous example, in Rails 3.0.x i get:

>m1.models_2.any? >false >m1.models_2.size >0

This means, new objects are not being considered

This exact same query in Rails 3.1:

>m1.models_2.any? >true #OMG!! >m1.models_2.size >1 So, the solution is:

>m1.models_2.all.any? >false >m1.models_2.all.size >0

If I have to change ALL my relationships with .all, I'm in a big trouble... am I missing something? Thank you very much.

Looking a thttps://github.com/rails/rails/blob/v3.1.0/activerecord/lib/active_record/relation.rb#L141-143 (and the same in v3.0.10, for example) I can't figure out why that isn't the same, since the code is pretty much the same, so I'm probably missing something.

That said, you have 3 ways of querying the size of an ActiveRecord relation:

* #length will load all the objects into an array (unless they are already loaded) and then return the array's size. * #count will force a DB count and return that result, without loading the model instances into memory. * #size will, if the objects are already loaded in an array, return the #length, or otherwise call #count.

So you don't need to force an "all", that will load your objects in memory. Just calling #count should do.

Cheers, -foca

I believe that this is a rails 3.0 bug.

In both 3.0 and 3.1 ActiveRecord::Relation’s #build is an alias for #new. But somehow, in rails 3.0 this behaviour is not the same, #build will increase the “size counter” and #new will not.

This was probably fixed in rails 3.1.

Everton Moreth

This is a real problem, waiting for news

I can confirm what you have described: https://gist.github.com/1248588

In 3.0 there were inconsistencies between calling 'new' and 'build' on an association. I consider this a bug. In 3.1 the inconsistencies are tidied up, resulting in the behaviour you describe.

If you want to issue a COUNT query to the db, use #count rather than #size.

Cheers