Search code examples
ruby-on-railsarraysruby-on-rails-5destroy

What's the fastest way to delete an array of my model objects?


I'm using Rails 5. I want to delete a bunch of records from a table. I have

currencies = CryptoCurrency.order('latest_market_cap_in_usd desc').limit(num_currencies)
current_index_currencies = CryptoIndexCurrency.all.pluck(:crypto_currency_id)

currencies_to_remove = current_index_currencies - currencies
...
currencies_to_remove.each do |currency|
  currency.destroy
end

where "currencies_to_remove" is supposed to contain an array of all the models that I want to delete. But I get the below error when iterating over the list

2.4.0 :005 > svc.create_index
   (0.4ms)  SELECT "crypto_index_currencies"."crypto_currency_id" FROM "crypto_index_currencies"
  CryptoCurrency Load (1.5ms)  SELECT  "crypto_currencies".* FROM "crypto_currencies" ORDER BY latest_market_cap_in_usd desc LIMIT $1  [["LIMIT", 12]]
NoMethodError: undefined method `destroy' for 1020:Integer
    from /Users/davea/.rvm/gems/ruby-2.4.0/gems/whenever-0.9.7/lib/whenever/numeric.rb:10:in `method_missing'
    from /Users/davea/Documents/workspace/cindex/app/services/crypto_index_service.rb:17:in `block in create_index'
    from /Users/davea/Documents/workspace/cindex/app/services/crypto_index_service.rb:16:in `each'
    from /Users/davea/Documents/workspace/cindex/app/services/crypto_index_service.rb:16:in `create_index'
    from (irb):5
    from /Users/davea/.rvm/gems/ruby-2.4.0/gems/railties-5.0.4/lib/rails/commands/console.rb:65:in `start'
    from /Users/davea/.rvm/gems/ruby-2.4.0/gems/railties-5.0.4/lib/rails/commands/console_helper.rb:9:in `start'

Solution

  • That's because currencies_to_remove contains the indexes of the models to remove, rather than the models. Thus, destroy method is undefined.

    The fastest way to delete them is going to be delete method on the model class:

    CryptoCurrency.delete(currencies_to_remove)
    

    But if you need to call the callbacks on destroy, you might need the destroy method:

    CryptoCurrency.destroy(currencies_to_remove)
    

    Note, that the destroy method will raise the RecordNotFound exception, if any record in specified array is not found