url optimization in rails? - ruby-on-rails

Hello I want to create seo optimize url in rails.Same like done in stackoverflow.
Right now this is my url
http://localhost:3000/questions/56
I want to make it something like this:-
http://localhost:3000/questions/56/this-is-my-optimized-url
i am using restful approach.
is there any plug-in available for this.

I know you asked for a plugin, but a dead simple approach is just to override the to_param method in your model. You can just append the seo name to the id.
For example:
class Question < ActiveRecord::Base
#has attribute name.
def to_param
"#{id}-#{name.parameterize}"
end
end
The path/url helpers will then generate a path like so:
show_question_path(#question)
>> /questions/12345-my-question-name
You do not need to do anything to your routes.
Your controller will remain Question.find(params[:id]) as the param will have to_i called on it, which will strip off the name and just return the id.

I highly recommend looking into the friendly_id plugin. The FriendlyId Guide is a great place to start. I have been using this in production for a number of months and it works great.
Using the cached slugs feature makes this a very scalable solution. Additionally I'd recommend using it combination with stringex if you deal with non-ASCII characters.

Related

Unable to change the parameter from id to a custom variable in Rails

I've been racking my brain trying to figure out something that should be extremely simple, so I'm sure I'm just overlooking something and a fresh set of eyes might be useful since all my code is seemingly blurring together. I'm attempting to create vanity URLS for a site that allows users to create categories and then post relevant stories based on those categories. So, for example, I would like users to access /categories/movies in order to view the movie section. If I set it up to use the category id, /categories/1, it works no problem. For whatever reason, rails keeps trying to use the id parameter to find the category as opposed to the title parameter. I'm using Ruby 2.0.0 and Rails 4.0. I've read that the "find_by" method will become deprecated soon, so if there's a better way to handle this, that'd be great. Here's the relevant code:
Categories Controller
def show
#categories = Category.find_by_title(params[:title])
#category = Category.find_by_title(params[:title])
#posts = Post.where(category: set_category).all
end
Routes.rb
resources :categories
get "/categories/:title" => "categories#show"
Terminal readout when rendering page
Processing by CategoriesController#show as HTML
Parameters: {"id"=>"Movies"}
Just to reiterate, the parameters should read {"title"=>"Movies"} not id. Like I said, I'm sure it's something extremely simple that I've overlooked. Any help would be appreciated. Thanks.
I had to implement vanity urls as well and followed this blog post/tutorial
You pretty much create a slug in your model with the vanity-url, so
class Category < ActiveRecord::Base
def slug
title.downcase.gsub(" ", "-")
end
def to_param
"#{slug}"
end
end
Your show action in your controller would use the find_by_slug method
I think there is a gem that does this as well called friendly_id and here is a railscast but I have not personally used it
Hope this helps

How to use a friendly id only in one namespace

I'm using the gem friendly_id in rails 4 to make nice urls for my user's product listings. It works by overriding the to_param. Now it is working wonderfully in the Shop namespace which is the public facing part of my site however in the Admin namespace I'd rather be using the regular ids because I don't need them there and I'd rather the urls be shorter.
I thought this would be easy but after digging it actually seems somewhat complicated. The to_param, because it's part of the model, has no real concept of what controller it is being called in. So the only option I see is to override url_for so it uses id in the Admin namespace. I'm not sure how to do that and if that really is the best coarse of action because messing with url_for seems a little dangerous.
With FriendlyId5 finders are not overwritten by default.
friendly_id :foo, use: :slugged # you must do MyClass.friendly.find('bar')
# or...
friendly_id :foo, use: [:slugged, :finders] # you can now do MyClass.find('bar')
This way, I guess you can use the first option, and depending on the namespace call
MyClass.friendly.find('params[:id]')
or
MyClass.find('params[:id]')
You might want to use friendly_id in case if you do not want to mess with to_params. It is easier to implement to make excellent friendly urls that are both machine and human friendly
http://kapilrajnakhwa.com/blogs/user-friendly-urls-with-friendly_id-gem-in-rails-4

How do I set up a route to a url that ends with and number/id in ruby on rails?

How do I route to a page that ends with an id?
E.G.
before: site.com/messages/8
after: site.com/messages/terrytibbs
I've tried:
match "/messages/:username" => "messages#id"
No luck so far. Just trying to make the url have a little more meaning by replacing the number with the username of the user the current user is talking to.
Kind regards
If you want something simple without having to change your routes etc, why not do this:
class Message
def to_param
"#{id}-{username}"
end
...
end
Assuming you have a username attribute on your message. That will make your url look like:
site.com/messages/8-terrytibbs
this works because of the following (say in irb):
"8-terrytibbs".to_i
=> 8
and when rails looks up your message in your controller it will do the same thing to the id parameter.
EDIT: there is an excellent railscast on this here: http://railscasts.com/episodes/63-model-name-in-url and an updated version here: http://railscasts.com/episodes/63-model-name-in-url-revised
Take a look at friendly_id gem. I think it's what you need.
FriendlyId is the "Swiss Army bulldozer" of slugging and permalink plugins for Ruby on Rails. It allows you to create pretty URLs and work with human-friendly strings as if they were numeric ids for Active Record models.
Using FriendlyId, it's easy to make your application use URLs like:
http://example.com/states/washington
instead of:
http://example.com/states/4323454
Your route is set up correctly you have to change the Controller to use the correct parameters.
Assuming your MessagesController does:
def id
User.find(params[:id])
end
change to:
def id
User.find_by_username(params[:username])
end
I would also recommend adding indexing on user name.
You're on the right track, you just need to make sure the route is pointing at a proper action on the controller, like so:
Say the action you want this to point to is named show, here is how you would define the route:
match 'messages/:username' => 'messages#show'
Then if you navigate to messages/8, params[:username] will be set to '8' (parameters always come in as String's.
Likewise if you navigate to messages/terrytibbs, params[:username] will be set to 'terrytibbs'.
Try reading Chapter 3-3.5 of the Rails Routing Guide, it provides a good overview of how to bind parameters to a route like you are attempting to do.

Friendly URLs in Github

How has Github managed to get friendly URLs for representing repos of users? For a project called abc by username foo, how do they work around with a URL like: http://github.com/foo/abc. Are they fetching the abc model for the DB from the title in the URL (which sounds unreasonable as they are modifying the titles). How are they transferring the unique ID of the abc repo which they can fetch and show in the view?
The reason I ask is that I am facing a similar problem of creating friendlier URLs to view a resource. MongoDB's object IDs are quite long and make the URL look horrific. Is there a workaround? All the tutorials that demonstrate CRUD (or REST) URLs for a resource always include the object's unique ID(e.g. http://mysite.org/post/1 or http://mysite.org/post/1/edit. Is there a better way to do it?
Not having seen their code, I couldn't tell you exactly how they do it, but if you're using Rails there are at least two Ruby gems that will give you similar results:
Take a look at Slugged and friendly_id
http://github.com/foo/abc is a unique repository identifier (for that repo's master branch). I'd assume that somewhere they have a table that looks like:
repository-id | user-id | project-id
and are just looking up based on user and project rather than repository-id.
You'd need to do some domain-specific mapping between internal and user-friendly ids, but you'd need to make sure that was a 1:1 mapping.
See this rails cast on methods, gems and solutions to common problems you might get while modifying the application to use friendly urls.
http://railscasts.com/episodes/314-pretty-urls-with-friendlyid?view=asciicast
(although Ryan Bates deserves the rep+ for this)
I mocked a structure like this using FriendlyID and Nested Resources.
Essentially, use friendly ID to get the to_param-ish slugs in your routes, then set up nested resources. Using GitHub as an example:
routes.rb
resources :users do
resources :repositories
end
Then in your controller, say, for repositories, you can check the existence of params[:user_id] and use that to determine the user from the route. The reason I check for existence is because I did something like (roughly):
/myrepositories/:repository_id
/:user_id/:repository_id
So my controller does:
def show
#user = params[:user_id] ? User.find(params[:user_id]) : current_user
end
I followed this tutorial here to get started with this same project.
This is called URL rewriting if the web server does it (such as Apache), and routing when it happens in a web application framework (such as Ruby on Rails).
http://www.sinatrarb.com/intro#Routes
http://httpd.apache.org/docs/current/mod/mod_rewrite.html

How to create search engine friendly url for rails models?

I looked into this plugin called acts_as_permalinkable at github and found it to be useful. Do you know of any other plugin that generates search engine friendly urls for ruby on rails models in a better way?
friendly_id might do the trick for you.
acts_as_urlnameable does the trick as well. I haven't used permalinkable, so I can't say that it is better. Does it have some specific deficiencies that concern you?
It lives at: http://code.helicoid.net/svn/rails/plugins/acts_as_urlnameable/
there is always just to_params in your model which can display basically whatever you want. Just note that your methods in that model will have to change, when you use find.
e.g. in the post.rb file
def to_param
name.parameterize
end
and in your posts_controller.rb methods that usually pick up the params[:id] call, you just have to change them to:
#post = Post.find_by_name(params[:id])
no plugin, no fuss and still pretty urls.

Resources