Search code examples
ruby-on-railsrubyruby-on-rails-4

update_all clear my array in variable


My small service in Rails

class ReadUserService
  def self.read_users(count)
    users = Users.inactive.limit(count)

    users.update_all(status: User.statuses[:active])

    users.to_a
  end
end

When I not call update_all, users variable is correctly, but When I use update_all, my users variable is empty. How Can I stopped clear my array? I need return all users from db, which have inactive status before update_all


Solution

  • From the docs:

    Updates all records in the current relation with details given. This method constructs a single SQL UPDATE statement and sends it straight to the database. It does not instantiate the involved models and it does not trigger Active Record callbacks or validations. Values passed to update_all will not go through ActiveRecord's type-casting behavior. It should receive only values that can be passed as-is to the SQL database.

    As I highlighted: update_all does not load and instantiate the object in the relation. That means the users variable just holds a relation object but has not queried the database for matching records. The first time the relation tries to load records is in users.to_a. But at that point in time the record has already been changed (made active).

    To fix this, load the record first and update them later:

    def self.read_users(count)
      scope = Users.inactive.limit(count)
      users = scope.to_a
    
      scope.update_all(status: User.statuses[:active])
    
      users
    end