Reputation: 2071
I'm testing a rake task - update_city_status_for_users
:
task update_city_status_for_users: :environment do
User.update_city_statuses do |user, new_status|
# does something
end
end
Method User.update_city_statuses
:
def self.update_city_statuses(&block)
users_ids = Journey.valid.where.not(user_id: nil).pluck(:user_id) # Only journeys (valid) for route 1
users_with_journeys = self.where(id: users_ids)
Rails.logger.info "Only update users with at least one journey: #{users_with_journeys.count} users to update."
ActiveRecord::Base.transaction do
users_with_journeys.each do |u|
new_status = u.new_status?
if new_status != nil
begin
u.update!(city_status: new_status)
yield(u,new_status) if block_given?
rescue => exception
Rails.logger.error "Exception updating user with id #{u.id}. Exception: "+exception.to_s
end
end
end
end
end
And this is the test:
RSpec.describe do
describe "update_city_status_for_users" do
it 'updates users with their corespondent new city status: from nil to "Venice"' do
user = user_with_journeys(5, "Venice")
city_status_before_task = user.city_status
BicycleIsland::Application.load_tasks
Rake::Task['update_city_status_for_users'].invoke
expect(city_status_before_task).to eq nil
expect(user.city_status).to be_an_instance_of CityStatus
expect(user.city_status.city).to eq "Venice"
end
end
end
user_with_journeys
is defined where the user factories are and basically it creates a user with 5 journeys.
After task invocation inside the test I check the user variable (factory created):
user.city_status
# nil
However, when I pull the user from the database the association has been made and city_status is not nil:
User.find(user.id).city_status
# #<CityStatus id: 6, level: 6, city: "Venice", distance: 1730, created_at: "2020-11-18 17:11:32", updated_at: "2020-11-18 17:11:32", image_file_name: "Venice-1000.png">
Both users are the same:
User.find(user.id) == user
# true
However, the city_status is not associated when calling the factory directly. That's not the behavior I was expecting. I would expect to carry on the updates and associations that have been made.
I'm probably missing something? Could anyone help me to point it out?
Thanks!
Upvotes: 0
Views: 210
Reputation: 1940
Rails caches the model instances to avoid repetitive database queries. You'll need to call
user.reload
before your assertions to update the object with the latest values from the database.
Upvotes: 1