1

This is actually working (it returns the 5 artists with the most amount of tracks in a database)

def top_five_artists(genre_name)
  # TODO: return the 5 artists with the more tracks of genre `genre_name`
  Artist.joins(albums: { tracks: :genre }).where(genres: { name: genre_name }).group(:name).order("COUNT(*) DESC").limit(5)
end

but throws the following warning:

DEPRECATION WARNING: Dangerous query method (method whose arguments are used as raw SQL) called with non-attribute argument(s): "COUNT(*) DESC". Non-attribute arguments will be disallowed in Rails 6.1. This method should not be called with user-provided values, such as request parameters or model attributes. Known-safe values can be passed by wrapping them in Arel.sql(). (called from top_five_artists at /home/maxichalbaud/code/maxichalbaud/fullstack-challenges/03-AR-Database/03-ActiveRecord-Basics/Optional-01-Mapping-Existing-Database/app/queries.rb:18)

How would you refactor the "COUNT(*) DESC" line?

GMB
  • 216,147
  • 25
  • 84
  • 135
  • 2
    I think this is a duplicate of [**DEPRECATION WARNING: Dangerous query method**](https://stackoverflow.com/q/48897070/479863) because I can't think of how to order by `count(*) desc` without getting into a bunch of incomprehensible AREL code. So you could `order(Arel.sql('count(*) desc'))` to get rid of the warning. – mu is too short Feb 03 '20 at 21:05

1 Answers1

1

You can try this :

def top_five_artists(genre_name)
  Artist.joins(albums: { tracks: :genre })
        .where(genres: { name: genre_name })
        .group(:name)
        .order(Arel.sql('count(*) DESC'))
        .limit(5)
end

First, you can use order(Arel.sql('count(*) DESC')) to get rid of the warning of deprecation as mu_is_too_short mentioned above, then, you can write your code in multiple lines so that RuboCop won’t bother you with "This line is too long".

  • 1
    While this code block may answer the question, it would be best if you could provide a little explanation for why it does so. – nik7 Apr 26 '21 at 22:27