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.
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
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 ?
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?
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.
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.