Reputation: 5947
I have the following code, which works fine with no errors but the models never get saved...
myarray.each do |item|
r = MyModel.unscoped.where(:site_id => @site.id, :url => item['permalink_url']).first_or_initialize do |r|
r.title = 'asdasdadaddjfgnfd'
r.save!
end
end
Terminal shows the SQL SELECT statements when attempting to find the Models, but the UPDATE/INSERT statements never run.
What am I missing here?
Upvotes: 5
Views: 4988
Reputation: 5947
I solved this by using:
.first_or_initialize.tap() do |r|
But the comments below are also relevant
Upvotes: 6
Reputation: 12818
Rails first_or_*
methods invoke passed block only for initialize
or create
part. If the record is found, the methods just return it so passed block will never run. Check the source
So you can use block in first_or_*
methods only to initialize new items, not to update existing ones. Most likely, records with such conditions exist and don't get updated.
Try to move update code, something like
myarray.each do |item|
r = MyModel.unscoped.where(:site_id => @site.id, :url => item['permalink_url']).first_or_initialize
r.title = 'asdasdadaddjfgnfd'
r.save!
end
Upvotes: 8
Reputation: 3911
You're looking for first_or_create
. first_or_initialize
just initializes the object (possibly to prep for saving, but it doesn't have to be).
You're existing code would likely work as follows:
r = MyModel.unscoped.where(:site_id => @site.id, :url => item['permalink_url']).first_or_initialize do |r|
r.title = 'asdasdadaddjfgnfd'
end
r.save!
Upvotes: 3