Reputation: 513
My models and its associations are:
class Post < ActiveRecord::Base
has_many :comments
end
class Comment < ActiveRecord::Base
belongs_to :post
validates :commenter, :presence => true
end
Case1: Automatically save method is called when I tried below code.
@post = Post.find(3)
@comments = @post.comments
p @comments #=> []
p @comments.class #=> Array
if @comments.empty?
3.times do
@comments << @post.comments.build
end
end
p @comments.first.errors #=>{:commenter=>["can't be blank"]}
Case2: if I manually initialize same empty array to the @comments, auto save is not calling. for instance,
p @comments #=> []
p @comments.class #=> Array
if @comments.empty?
@comments = []
p @comments #=> []
3.times do
@comments << @post.comments.build
end
end
p @comments.first.errors #=>{}
What is the best solution to avoid auto save and please any one explain why the above code behave differently?
Upvotes: 0
Views: 3311
Reputation: 12818
Rails extensively uses monkey-patching, so rails Array is not the same thing as pure Ruby array. (Compare output from irb > [].methods
and rails c > [].methods
According to the documentation <<
method of has_many
collection
instantly fires update sql without waiting for the save or update call on the parent object
So most likely Rails have an "observer" of the collection events, and fires validation when you try to add new object.
In second snippet you use pure array (not has_many
collection), so the update action is not fired.
To avoid update action you don't need <<
at all
@post = Post.find(3)
@comments = @post.comments
if @comments.empty?
3.times do
@post.comments.build
end
end
p @comments.size
=> 3
Upvotes: 2