1

I'm in the following situation. The current url looks like the following:

/categories/Art

And I'm using name = location.pathname.split('/')[2] in order to grab the Art portion of the URL. Then, I send an AJAX the following path back to the controller: http://localhost:3000/sort?sortMethod=name&category=name or date, whichever link is clicked on.

Now in my controller I can use sort = params[:category] to get the string name, yet what I'd like to do with this string is sort an array by it. @categories is an array of objects and I'd like to call .sort_by(&:sort) yet it doesn't recognize the string value of sort = name. So now I'd like to convert this string into a proc in order to sort the array. Anyone know how I accomplish this?

Any help is greatly appreciated!

0

3 Answers 3

2

Convert it to a symbol first and then use Symbol#to_proc:

@categories.sort_by(&sort.to_sym)

However be sure that the users can't call anything malicious on your objects like:

http://localhost:3000/sort?sortMethod=destroy

One way of protecting yourself is to use attribute_accessible definitions in your model and then do

@categories.sort_by(&sort.to_sym) if Category.accessible_attributes.include? sort.to_sym
Sign up to request clarification or add additional context in comments.

4 Comments

How would you recommend I go about protecting myself from that? What are some common approaches to a similar situation?
Have a list of whitelisted methods. Do some like this: sort_by(&sort.to_sym) if whitelist.include?(sort)
I've added an example specific for ActiveRecord, but you can have a whitelist for any object.
Fyi, this method opens you up to a specific kind of DOS attack: tricksonrails.com/2010/06/… You may want to consider checking whether the attribute is accessible BEFORE converting the user input to a symbol.
0

The problem is not entirely clear, so you may need to adjust the following solution. However, the basic idea is taht it's possible to do something like:

Category.all.sort_by {|category| category.method(params[:category]).call }

1 Comment

While I was writing also Jakub answered. I think both solutions work; his solution is a shorthand to this one and could be preferred. Use mine if you need to be a little more flexible, e.g. if you want to handle errors whenever params[:category] contains a string that is not an instance method of Category (what happens if a user requests ...?sortMethod=a_method_that_does_not_exist or ...?sortMethod=destroy?)
0

Also, the "Art" portion of your url is available in Rails' params hash as params[:action], so you don't have to do location.pathname.split('/')[2].

1 Comment

I need to grab it in the javascript function, not the rails controller.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.