1
\$\begingroup\$

I am generating routes and responding to it dynamically by looking at the enum defined in the model. Is this safe and is there more proper method?

# Place
enum post_type: [:restaurant, :bar, :chill]

# routes  
scope '/places' do
    get '/:category', to: 'places#index', constraints: { category: Regexp.new( Place.post_types.keys.join("|") ) }
  end

# places_controller
def index
    if Place.respond_to? parmas[:category]
      @places = Place.send(params[:category]).order(:created_at).limit(10)
    end
end
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$
Place.send(params[:category])

Using raw user data with send is very dangerous, as it allows the user to call any method (params[:category] could be "delete_all" for example).
Using raw user data with responsd_to? can also be problematic, as this method exposes inner details of the class.

Instead, compare the user data against Place.post_types. It will look like this: (Untested)

 if  Place.post_types.has_key? params[:category]
   @places = Place.where(post_types: params[:category]).order(:created_at).limit(10)
 end

Also, dynamically creating a string for a regex is unreliable:

Regexp.new( Place.post_types.keys.join("|") )

It will break if a key contains any special characters, for example.

Instead of using a regex, test the data against Place.post_types.

EDIT: Actually, it seems this contraint is unneeded as it's tested in the controller.

\$\endgroup\$
2
  • \$\begingroup\$ The query that I got to work is Place.where(post_type: Place.post_types[params[:category]]) \$\endgroup\$
    – harinsa
    Oct 29, 2015 at 9:09
  • \$\begingroup\$ @harinsa: Looks good. \$\endgroup\$
    – Spike
    Oct 29, 2015 at 10:58

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.