generating permalink with resources rather than id in rails routes - ruby-on-rails

Is there a simple way of making rails routes to generate urls with permalink rather than id
what i mean is ..
resources :posts #=> generates urls like posts/12, posts/45/edit, ...
which can be used in controller as find(params[:id])
now with
def to_param
self.permalink
end
urls become /posts/what-is-rails, /posts/what-is-rails/edit,
now to find the record with permalink we still have to do
*find_by_permalink(params[:id])*
Now the question is, is there a easier way to generate urls with permalink in them

Use FriendlyId gem as seen at #314 Pretty URLs with FriendlyId Railscast.

Related

Display user#show url as www.fb.com/usrname and www.usrname.fb.com instead of showing www.fb.com/123, in rails 4.2.6

I am trying to show username instead of user_id i.e., (users/4).
i have tried with changing routes file, model file as:
class User < ActiveRecord::Base
def to_param
username
end
end
and routes file as:
get '/:username' => 'users#show'
on show action it must show as fb.com/username url.
thanks in advance.
You may use friendly_id gem for this. Here is Rails cast : Pretty URLs with friendly_id On how to use it. You can use the attribute/column you want in the URL.
With FriendlyId, it's easy to make your application use URLs like:
http://example.com/states/washington
instead of:
http://example.com/states/4323454

Route using underscores instead of spaces

Ruby on Rails 4.0. I have a 'Specialty' model that 'admins' can modify using the standard resource routes. However there is also a separate consumer facing controller that is used to display those 'Specialties' in a pretty fashion. As such I have the following routes:
get "specialty/:name" => "site#specialty", as: :site_specialty
resources :specialties
The site#specialty controller action is as follows:
def specialty
#specialty = Specialty.find_by_name(params[:name])
end
This results in urls like the following percent escaped routes:
/specialty/project%20management
I would rather have something like this:
/specialty/project_management
How do I replace the spaces with underscores and still look up the correct model in the controller action? Any side notes on security also appreciated
Try using to_param:
Model:
class Specialty < ActiveRecord::Base
def to_param
name.parameterize
end
end
Controller:
def specialty
#specialty = Specialty.find(params[:id])
end
That should do it...
References:
http://guides.rubyonrails.org/active_support_core_extensions.html#to-param
https://gist.github.com/cdmwebs/1209732
http://railscasts.com/episodes/63-model-name-in-url
The answer by #manishie is good, but there is also a gem that handles this for you (and much more), called Friendly ID. It is based on the same to_param trick as previously mentioned, but also has options to handle other special characters and handle collisions.
class Specialty < ActiveRecord::Base
extend FriendlyId
friendly_id :name
end
Specialty.friendly.find(params[:name])

friendly_id and routes.rb - rails

I'm currently using friendly_id gem in rails and noticed that if someone names a post "About" that it overwrites the /about path that I have assigned to a static page in my routes.rb file.
This is my current code:
extend FriendlyId
friendly_id :title, use: :history
If there are prior posts with the same name...it adds a --2. But friendly_id seems to ignore static routes in my routes.rb.
Is there a way to make friendly_id recognize and not overwrite these routes?
Thank you
FriendlyID includes a Reserved module which prevents a list of provided words from being used as friendly slugs. You could add your static routes to the reserved words array which would prevent someone from overwriting your routes.
From the FriendlyId RDocs
FriendlyId.defaults do |config|
config.use :reserved
# Reserve words for English and Spanish URLs
config.reserved_words = %w(new edit nueva nuevo editar)
end
If you still want to allow for a title that is reserved you can make a new method that FriendlyId would use for the slug. This piece from the RDocs explains that
Column or Method?
FriendlyId always uses a method as the basis of the slug text - not a column. It first glance, this may sound confusing, but remember that Active Record provides methods for each column in a model's associated table, and that's what FriendlyId uses.
Here's an example of a class that uses a custom method to generate the slug:
class Person < ActiveRecord::Base
friendly_id :name_and_location
def name_and_location
"#{name} from #{location}"
end
end
bob = Person.create! :name => "Bob Smith", :location => "New York City"
bob.friendly_id #=> "bob-smith-from-new-york-city"
You could create a method like :title_with_id or :title_with_rand. it's up to you and how you'd like the slugs to look.
You would also want to make sure your routes.rb has your static routes listed prior to the routes for with the friendly id. The first route dispatcher matches is where the request will be processed.

Rails app with another browser string

I have a question about browser string in rails.
For example i have rails app with routes:
resources :posts
and this resource create :
post/:id
post/21
post/167
post/356
but i create a simple blog and i want to rename ':id' to
post/some-name
post/another-name
post/another-different-name
in post i have title, text field
but i dont know how do this
I know that this can be achieved through manipulation of the :id
can you post some link with detailed answer on this question, or some simple example
You can of course put anything you want in the URL and actually there is railcast about it:
http://railscasts.com/episodes/63-model-name-in-url
It is preferable (read: easier) to also keep model.id in the URL, or it means that post name MUST be unique, otherwise you can put anything you want:
/post/2465-my-pretty-post-name
Also, there is a gem friendly_id and related railcast:
http://railscasts.com/episodes/314-pretty-urls-with-friendlyid
Hope that helps.
Why do you want to change /post/:id ?
You can achieve something like /post/:id/comments
You can do that using nested resources like this in your routes.rb
resources :posts do
resources :comments
end
Check here for more details
http://guides.rubyonrails.org/getting_started.html
If you add the to_param method to the model then you can use that within your URL system.
class SomeModel < ...
def to_param
self.title
end
end
Then inside your controller, setup a filter to fetch the model using the title attribute instead of the ID attribute which is used for the find method.
before_filter :setup_record
def setup_record
#record ||= Record.find_by_title(params[:id])
end
You will have to ensure that your title stays unique and if you change it then you will either have to discard all other previous URLS or keep a history of older names.

Ruby on rails to_param with multiple fields for SEO

I am trying to make my urls prettier and still use restful resources. I understand that you can override the to_param method if you object has a name property like this:
def to_param
self.name
end
which will give you the route /:model/:name. This is all straightforward, but I have to be capable of having the same name with multiple different languages. I haven't been able to find a blog entry on how to do this, so how can i override the to_param method to provide me a route similar to /:model/:language/:name ?
You could always do:
/language/:language/model/:name
You'd do this with nested routes:
map.resources :languages do |l|
l.resources :profiles
end
Then your route would be:
langauge_profile_url('spanish', #profile)
However...
Depending on what you're trying to do you might be better of using the built in rails i18n stuff. Is this so users can browse the site in different languages??

Resources