How to use new_record?, changed? and persisted? methods in rails in this example
11,234
Solution 1
You can try first_or_initialize along with assign_attributes
new_data.each do |c|
car = Cars.where(:brand => c[:brand]).first_or_initialize
new_records +=1 if car.new_record?
car.save # first save the initialized AR
car.assign_attributes(c)
changed_records +=1 if car.changed?
car.save
end
Solution 2
I might not answer your question directly but I will try explain the Activerecord lifecyle methods.
new_record?
car = Car.new # => initialize a new Car object
car.new_record? # => true
persisted?
car.save
car.persisted? # => true
changed?
car.model = 'New release model S'
car.changed? # => true
destroyed?
car.destroy
car.destroyed? # => true
Author by
Admin
Updated on June 09, 2022Comments
-
Admin almost 2 years
Trying to undestand new record?,changed ? and persisted ? on the example below.
How, this code has this result:
# NOW # there is 0 new record after running new_data array # there is 0 changed record(s) after running new_data array # there is 3 persisted record(s) after running new_data array
Trying to come to this result:
# WANT #there is 1 new record(s) after running new_data array #there is 1 changed record(s) after running new_data array #there is 2 persisted record(s) after running new_data array
*Question is: *
How to do it?. Want to record the number of changed and new records.
Cars.delete_all original_data = [ {:brand => 'Mercedes', :used => false, :year => 2000 }, {:brand => 'Honda', :used => true , :year => 2000 }, {:brand => 'Nissan', :used => false, :year => 2000 } ] new_data = [ # updating year to 2013 {:brand => 'Mercedes', :used => false, :year => 2013 }, # new record {:brand => 'Tesla', :used => false, :year => 2013 }, # same data {:brand => 'Nissan', :used => false, :year => 2000 } ] # create new cars original_data.each do |c| Cars.create(c) end # updates persisted = 0 new_records = 0 changed_records = 0 new_data.each do |c| car = Cars.where(:brand => c[:brand]).first_or_create persisted +=1 if car.persisted? new_records +=1 if car.new_record? changed_records +=1 if car.changed? end puts "there is #{new_records} new record(s) after running new_data array" puts "there is #{changed_records} changed record(s) after running new_data array" puts "there is #{persisted} persisted record(s) after running new_data array"
*UPDATE*
code according to answer: - attempt to change only 1 record, not 2.
# updates persisted = 0 new_records = 0 changed_records = 0 new_data.each do |c| car = Cars.where(:brand => c[:brand]).first_or_initialize car.assign_attributes(c) persisted +=1 if car.persisted? new_records +=1 if car.new_record? changed_records +=1 if car.changed? car.save end there is 1 new record(s) after running new_data array there is 2 changed record(s) after running new_data array there is 2 persisted record(s) after running new_data array
-
NBSamar over 2 yearsCar.new_record?, here we need to check for Car's instance, which is stored in car variable here. So, the correct way would be car.new_record?
-
Kaka Ruto over 2 yearsYou were right @NBSamar. Updated!