Rails Validate String for URL "Safety" - ruby-on-rails

Let's say I have this route:
get 'post/:title' => 'post#show' , :as => 'show_post'
Anyone is able to create posts, and pick their own titles.
I don't want the title to contain characters like '/', '[', ']' as it could lead to bad urls generated with the helper method show_post_path('blah'). I'm sure there are other things than those character I mentioned I should be looking out for.
I'm looking for a way to validate against this in the post model.
/ Thanks

You can use Rails parameterize method to validate the string
Ex-
result = yourstring.parameterize
here is source http://apidock.com/rails/ActiveSupport/Inflector/parameterize

I think the best way to make it will be use gem
friendly_id

Related

Custom URLs in rails app

I'm trying to write a simple CMS in rails that will allow text urls rather than the standard /posts/show/<id>.
I have a model that has a title and body, I would like to replace spaces in the title and use it as the url.
I also want to have the url at the root level, not past /pages/show.
Take a look at this gem friendly_id, is used for create url from fields of the model storing it on database. Otherwise, you can create the route that you want example get 'pages/show', home#index and pointing wherever you want.
While the friendly_id gem is really nice, it's quite heavy for such a simple need. You might consider a lighter alternative approach : https://github.com/johnotander/urls_for_humans
You can override your rails urls by setting them like this:
get 'posts' => 'posts#index'
In your routes.
But since you want to format the url for the show action (which depends on a specific id for each item in posts) your best bet is to use the awesome friendly_id gem.
See: https://github.com/norman/friendly_id
Some resources:
http://railscasts.com/episodes/314-pretty-urls-with-friendlyid
http://blog.teamtreehouse.com/creating-vanity-urls-in-rails
I have figured out how to do what I wanted to do.
I am setting a route to the root url with a parameter like this (config/routes.rb):
get ':title', to: 'pages#show', as: :page
Now I have a pages controller that was generated by rails generate scaffold Page title:string body:text
which has a function set_page which I changed to do this (app/controllers/pages_controller.rb):
def set_page
#page = Page.find_by("title" => params[:title])
end

Rails: Generate URL without parameters

For example I have simple routes like:
get 'something/:param' => 'controller#action'
Request path in this case is /something/123 for example
Being in controller how to generate URL w/o parameter(s) like /something using Rails features?
Other examples:
get 'something/:param/action' => 'controller#action': '/something/action'
get 'something/:param/:param2' => 'controller#action': '/something'
You mean like this? You just get rid of the :param.
get 'something/' => 'controller#action'
get 'something/action' => 'controller#action'
If you are looking to protect or obscure the ids in the routes, or simply have nicer looking urls, then you might want to try the friendly_id gem.

Rails "pretty URLs", using entries/23 or 2011/07/some-post-slug-here for creating URLs via helpers

I'm attempting to create "pretty URLs" for linking to posts in a blog. I want to maintain access to the blog entries via entries/23 and 2011/07/some-post-slug-here as I only generate a slug once an entry has been published (just in case the title of the posts changes, and, though not a strict requirement, I would prefer to be able to edit/delete posts via the entries/23 style URL. Currently, the appropriate part of what I have in my config/routes.rb:
root :to => 'entries#index'
resources :entries
match ':year/:month/:slug' => 'entries#show', :constraints => {
:year => /[0-9][0-9][0-9][0-9]/,
:month => /[0-9][0-9]/,
:slug => /[a-zA-Z0-9\-]+/
}, :as => :vanity_entry
and I use this (in my application helper) function for creating the links:
def appropriate_entry_path entry
if entry.published
vanity_entry_path entry.published_on.year.to_s, entry.published_on.month.to_s, entry.slug
else
entries_path entry
end
end
def appropriate_entry_url entry
if entry.published
vanity_entry_url entry.published_on.year.to_s, entry.published_on.month.to_s, entry.slug
else
entries_url entry
end
end
Basically, I check if the article is published (and therefore has a slug) and then use that URL/path helper, or otherwise use the default one.
However, when trying to use this, I get the following from Rails:
No route matches {:slug=>"try-this-one-on-for", :month=>"7", :controller=>"entries", :year=>"2011", :action=>"show"}
I have tried a few different solutions, including overriding to_param in my Entry model, however then I would have to create match routes for the edit/delete actions, and I would like to keep my routes.rb file as clean as possible. Ideally, I would also love to lose the appropriate_entry_path/appropriate_entry_url helper methods, but I'm not sure that this is possible?
Is there any thing I am missing regarding routing that might make this easier and/or is there any specific way of doing this that is the cleanest?
Thanks in advance.
You might want to take a look at friendly_id. It's a gem for creating seo friendly slugs :)
I found the issue with what I had been doing, the regex for :month in the route wanted two numbers, whereas I was only passing in one number. Anyways, I decided that the URLs look nicer (in my opinion) without the month padded to 2 digits, so I updated my route accordingly.

Rails query string with a period (or full stop).

I am currently trying to get a handle on RoR. I am passing in two strings into my controller. One is a random hex string and the other is an email. The project is for a simple email verification on a database. The problem I am having is when I enter something like below to test my page:
http://signup.testsite.local/confirm/da2fdbb49cf32c6848b0aba0f80fb78c/bob.villa#gmailcom
All I am getting in my params hash of :email is 'bob'. I left the . between gmail and com out because that would cause the match to not work at all.
My routing match is as follows:
match "confirm/:code/:email" => "confirm#index"
Which seems simple enough for what I need. I am having a hard time trying to figure out what the deal is and really how to even search for an answer. Any help or guidance would be greatly appreciated.
match "confirm/:code/:email" => "confirm#index", :email => /.*/
Also it would be better to set get method here, I think
get "confirm/:code/:email" => "confirm#index", :email => /.*/
Your problem is that Rails is trying to interpret .villa#gmailcom as a format specification (such as .html or .json). AFAIK, the standard work around (or at least the one I use) is to add this to your route:
:requirements => { :email => /.*/ }
This tricks Rails into not trying to be clever about what :email contains.
I'm not surprised that you couldn't find anything, googling for "#" or "." doesn't do anything useful.

Rails 3 routes with non-numeric id's

I have an object that by necessity has an id that looks something like "1.3.6.1.4.1.25623.1.0.14377". When I try to create a link that uses the id (such as link_to my_object(object.id)), Rails 3 barfs and says that no route exists.
I have verified that I have a valid route in place by trying link_to my_object(1). Rails doesn't have a problem with creating this link.
Any ideas?
Thanks in advance!
I've figured it out... By default, Rails freaks when a period (.) is found in a parameter field (in this case id). To change this behavior, simply add a :constraints directive to your route statement and tell it explicitly what the parameter should look like. In my case it turned out that the following fixed the problem:
resources :nvts, :constraints => { :id => /[0-9\.]+/ }
Thanks to Avdi Grimm for his most helpful blog post.
Maybe you should override in your model the method to_param, Rails uses it to generate id for routing.
Usually it looks like this:
def to_param
object.parameterize
end
It gets the model's name and use as id in route.

Resources