Ryan
Ryan

Reputation: 18109

Rails/ActiveRecord Order Issue with string vs symbol

I'm having an issue applying a dynamic order method on a Rails Active Record query. The order by field and direction are dynamic based on the request params. When specifying them as a string, it gets tripped up on ambiguous field names. When specifying as a symbol, it's fine. How can I dynamically make this query with a symbol?

This:

subject = subject.order('id desc')

Results In SELECT DISTINCT "projects"."id", id AS alias_0 FROM... and gives a PG::AmbiguousColumn: ERROR: column reference "id" is ambiguous error.

When specifying this using symbols, Active Record correctly puts it all together without the ambiguity:

subject = subject.order(id: :asc) 

So how can I convert or use this method dynamically, such as:

subject = subject.order(params[:order_by] + ' ' + params[:order_direction])

Side note: There are joins and other complexity happening elsewhere in the query which I'm assuming is contributing to the issue (multiple id fields), but again as symbols Active Record figures it all out properly. Also, the order_by and order_direction in the params example above are being whitelisted, so SQL injection is not an issue.

Upvotes: 0

Views: 1373

Answers (2)

Usman Khan
Usman Khan

Reputation: 388

Short answer

subject = subject.order(params[:order_by].to_sym => params[:order_direction].to_sym)

Upvotes: 0

Dmitry Kukhlevsky
Dmitry Kukhlevsky

Reputation: 276

You could create a hash with symbolized keys like this:

order = {}
order[params[:order_by].to_sym] = params[:order_direction]
subject = subject.order(order)

Not sure that this will prevent the AmbiguousColumn error, though

Upvotes: 1

Related Questions