So far, the "common" way to get a random record from the Database has been:
# Postgress
Model.order("RANDOM()").first
# MySQL
Model.order("RAND()").first
But, when doing this in Rails 5.2, it shows the following Deprecation Warning:
DEPRECATION WARNING: Dangerous query method (method whose arguments are used as raw SQL) called with non-attribute argument(s): "RANDOM()". Non-attribute arguments will be disallowed in Rails 6.0. 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().
I am not really familiar with Arel, so I am not sure what would be the correct way to fix this.
If you want to continue using order by random()
then just declare it safe by wrapping it in Arel.sql
like the deprecation warning suggests:
Model.order(Arel.sql('random()')).first # PostgreSQL
Model.order(Arel.sql('rand()')).first # MySQL
There are lots of ways of selecting a random row and they all have advantages and disadvantages but there are times when you absolutely must use a snippet of SQL in an order by
(such as when you need the order to match a Ruby array and have to get a big case when ... end
expression down to the database) so using Arel.sql
to get around this "attributes only" restriction is a tool we all need to know about.
Edited: The sample code is missing a closing parentheses.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With