I’ve added a scope to a Rails model that allows for searching based on a specified parameter field using a range. Here is what it looks like:
scope :upcoming, lambda { |field|
where("to_char(#{field}, 'DDD') BETWEEN :alpha AND :omega",
alpha: Time.now.advance(days: 4).strftime('%j'),
omega: Time.now.advance(days: 8).strftime('%j'),
)
}
Event.upcoming(:registration) # Query all events with registration shortly.
Event.upcoming(:completion) # Query all events with completion shortly.
The above works fine, however in creating I read the Ruby on Rails Guides and found the following:
Putting the variable directly into the conditions string will pass the variable to the database as-is. This means that it will be an unescaped variable directly from a user who may have malicious intent. If you do this, you put your entire database at risk because once a user finds out he or she can exploit your database they can do just about anything to it. Never ever put your arguments directly inside the conditions string.
Although the scope is currently never called with a user parameter, I am curious if a way exists of setting the field without using the interpolation in order to better conform with the above recommendation. I’ve tried using another named parameter, however this will escape the field with quotes (and thus cause it to fail). Any ideas?
I would recommend validating the
fieldparameter against the model’s attributes, essentially using the model as a whitelist for values that are allowed to be passed. Something like this: