Build association and its size issue

I wonder id it is normal behaviour that when building an assosiation
‘build’ method , the returned size of association array changes despite
the
objet is nt saved yet ? Here is a short exampe to illustrate that:

class User < ActiveRecord::Base
has_many :posts, dependent: :destroy
end

class Post < ActiveRecord::Base
belongs_to :user
end

Nothing complex until now. When I play with that in the console:
Loading development environment (Rails 4.2.0)
irb(main):001:0> user = User.first
User Load (0.0ms) SELECT “users”.* FROM “users” ORDER BY
“users”.“id”
ASC LIMIT 1
=> #<User id: 1, name: “toto”, created_at: “2015-01-16 11:18:41”,
updated_at: “2015-01-16 11:18:41”>
irb(main):002:0> user.posts.size
(0.0ms) SELECT COUNT(*) FROM “posts” WHERE “posts”.“user_id” = ? [[
“user_id”, 1]]
=> 0
irb(main):003:0> post = user.posts.build(title: ‘ruby’)
=> #<Post id: nil, user_id: 1, title: “ruby”, created_at: nil,
updated_at:
nil>
irb(main):004:0> user.posts.size
=> 1
irb(main):005:0>

As you see the size of user posts is changed by 1. Why ? The post is not
still saved to the database. The user_id is nil. I had to apply some
validation before adding a new post tp ths user, that’s why I wonder if
it
is normal adn how to display just the existing User posts without using
‘select’ for example.

Rails version: 4.2.0, Ruby 2.1.5

Thank you.

On 20 January 2015 at 09:04, Javix [email protected] wrote:

end
[[“user_id”, 1]]
validation before adding a new post tp ths user, that’s why I wonder if it
is normal adn how to display just the existing User posts without using
‘select’ for example.

You have not saved it to the database but you have added it to the
users posts in memory. If you reload user it will revert to 0, and
you will lose the built post. If you want to check what it is in the
database then fetch the user to a new variable.
user1 = User.first
then user1.posts.size will be 0

Colin

On Tuesday, 20 January 2015 10:15:17 UTC+1, Colin L. wrote:

has_many :posts, dependent: :destroy

“users”.“id”

nil>

You have not saved it to the database but you have added it to the
users posts in memory. If you reload user it will revert to 0, and
you will lose the built post. If you want to check what it is in the
database then fetch the user to a new variable.
user1 = User.first
then user1.posts.size will be 0

Colin

So it is normal because AR does not make a new query to the DB and
operates
on the existing cached collection. What if instead of making the same
query
to find the same user:

user1 = User.first

I’ll do like that:
user.posts(force_reload: true).size

it works as needed and it seems like force_reload is false by default.
What
do you think ?

On 20 January 2015 at 09:25, Javix [email protected] wrote:

irb(main):001:0> user = User.first
=> #<Post id: nil, user_id: 1, title: “ruby”, created_at: nil,
is normal adn how to display just the existing User posts without using

it works as needed and it seems like force_reload is false by default. What
do you think ?

I think just user.reload would do it. It is not something I have had
to do often, why would one build an association and then want to throw
it away again in the same action?

Colin

On Tuesday, 20 January 2015 10:56:09 UTC+1, Colin L. wrote:

method , the returned size of association array changes despite the

[[“user_id”, 1]]
not

you will lose the built post. If you want to check what it is in the
query

I think just user.reload would do it. It is not something I have had
to do often, why would one build an association and then want to throw
it away again in the same action?

Why do I want it - because I’d like to run a validation callback before
saving an element of the collection. For example, an Account has_many
Operations. So I create an Operation like that in the
OperationsController:

def create @operation = @account.operations.new(operation_params)
if
@operation.save redirect_to @account, notice: t(:created_success,
model: Operation.model_name.human) else
render “new” end end

What I’d like to do is to check the sum to be withdrawn in the above
operation so that the balance of the account not to be negative. That’s
how
I
discovered the described behaviour.