Pretty URL in Rails when linking
If you are willing to accept: http:/.../1234-title-text you can just do:
def to_param
[id, title.parameterize].join("-")
end
AR::Base.find
ignores the bit after the id, so it "just works".
To make the /title go away, try naming your route:
map.post ':id', :controller => 'posts', :action => 'show', :conditions => {:id => /[0-9]+-.*/ }
Ensure this route appears after any map.resources :posts
call.
Rails POST forms to pretty URL
Your routes are given an automatic named path that you can see by typing rake routes
. For example:
new_flag GET /flags/new(.:format) {:action=>"new", :controller=>"flags"}
You can refer to the path by using new_flag_path
or new_flag_url
Your form_tag
entry is kinda screwy. Instead of having a separate find
method you could also use the index
method, but that's your choice.
You may find it easier to use a standard redirect_to
to redirect to a prettier URL based on inputs. If you don't want the redirect, then you'll need to use jQuery to change your form's action method dynamically. Searches typically use ugly GET parameters.
So I would change your code to look like this:
routes.rb
get 'routes/:from/to/:to' => 'finder#routes', :as => :find_from_to
post 'routes/find' => 'finder#find', :as => :find
_form.html.erb
<% form_tag find_path, :method => :post do %>
<%= label_tag(:from, "From:") %>
<%= text_field_tag(:from) %>
<%= label_tag(:to, "To:") %>
<%= text_field_tag(:to) %>
<%= submit_tag("Go") %>
<% end %>
finder_controller.rb
class FinderController < ApplicationController
def index
end
def find
if params[:from].blank? or params[:to].blank?
render :action => "invalid_results" and return
end
@from = Location.find_by_code(params[:from].upcase)
@to = Location.find_by_code(params[:to].upcase)
if @from.nil? or @to.nil?
render :action => "invalid_results" and return
end
redirect_to find_from_to_path(@from, @to)
end
def routes
@routes = Route.find_all_by_from_location_id_and_to_location_id(params[:from], params[:to])
end
end
How to make pretty url's with scopes using friendly_id?
You need friendly_id
only to create slugs based on title of the category. If you want to make slug unique in scope of category you can use special friendly_id module to solve this problem.
To make nice nesting in url you can do something like this in your routes:
get 'blog/:category', to: 'articles#index', as: "category"
Something like this in your articles controller:
class ArticlesController < ApplicationController
def index
@category = Category.friendly.find(params[:category])
@articles = @category.articles
respond_to do |format|
# and so on...
end
end
end
And something like this in your views:
link_to category.title, category_url(category)
Clean url with rails
Answering the question #1:
I don't know the details of what's your overall goal, but if you'd like
to have such URLs that are based on records from the database - then yes: it's
a good approach.
Answering question #2 (regarding slugs):
I'd rather use something much more elaborate and well tested like:
https://github.com/norman/friendly_id
My 50 cents about some other things:
Is this one of your first projects in Ruby/Rails? If so - congratulations! :)
I'm asking because I noticed that you're using camel case here and there...
Also:
user_id = url.id.to_i
Why do you call this #to_i method here? Did you set up this id as a string
or something?
Hope this helps
Rails Pretty URL with Decimals
Use the :requirements => { :param_name => pattern_regex } param.
DECIMAL_PATTERN = /\A-?\d+(\.\d+)\z/.freeze
map.connect 'stores/near/:longitude/:latitude',
:controller => 'stores', :action => 'index',
:requirements => { :longitude => DECIMAL_PATTERN, :latitude => DECIMAL_PATTERN }
Parameters with dots on the URI
create a directory structure (with nested routes + pretty urls, ...)
The part of the code you should look at is:
class Location < ActiveRecord::Base
belongs_to :states
end
and it should be
class Location < ActiveRecord::Base
belongs_to :state
end
Another note, although not related to the error you are getting, Ruby programmers usually prefer array.each
than for item in array
.
Is it worth using pretty URLs if you don't care about SEO/SEM
It's always worth it if you just have the time to do it right.
- Friendly-urls look a lot nicer and they give a better idea where the link will lead. This is useful if the link is shared eg. via instant message.
- If you're searching for a specific page from browser history, human readable url helps.
- Friendly url is a lot easier to remember (useful in some cases).
- Like said earlier, it is also a lot easier to communicate verbally (needed more often than you'd think).
- It hides unnecessary technical details from the user. In one case where user id was visible in the url, several users asked why their user id is higher than total amount of users. No damage done, but why have a confused user if you can avoid it.
how do I make the URL's in Ruby on Rails SEO friendly knowing a @vendor.name?
All of these solutions use find_by_name
, which would definitely require having an index on that column and require they are unique. A better solution that we have used, sacrificing a small amount of beauty, is to use prefix the vendor name with its ID. This means that you dont have to have an index on your name column and/or require uniqueness.
vendor.rb
def to_param
normalized_name = name.gsub(' ', '-').gsub(/[^a-zA-Z0-9\_\-\.]/, '')
"#{self.id}-#{normalized_name}"
end
So this would give you URLs like
/1-Acme
/19-Safeway
etc
Then in your show action you can still use
Vendor.find(params[:id])
as that method will implicitly call .to_i
on its argument, and calling to_i
on such a string will always return the numerical prefix and drop the remaining text- its all fluff at that point.
The above assumes you are using the default route of /:controller/:action/:id
, which would make your URLs look like
/vendors/show/1-Acme
But if you want them to just look
/1-Acme
Then have a route like
map.show_vendor '/:id', :controller => 'vendors', :action => 'show'
This would imply that that it would pretty much swallow alot of URLs that you probably wouldnt want it too. Take warning.
Related Topics
Regular Expression to Match Only the First File in a Rar File Set
Rails Adding Multiple Objects to an Empty Array
Kernel_Require.Rb:55:In 'Require': Cannot Load Such File Error
Rmagick How to Convert Image in Memory
Ruby Open-Uri Can't Open Url (M1 MAC)
How to Emit Yaml in Ruby Expanding Aliases
Carrierwave and Correct File Extension Depending on Its Contents
Why Doesn't Puts() Print in a Single Line
Rails Form Data Not Getting Saved to Db
How to Reset Boolean to "Default: False" at End of Day
How to Transform the Utf8 Chars to Iso8859-1
Ternary Expression with "Defined" Returns "Expression" Instead of Value
Regex Negative Lookbehind in Ruby Doesn't Seem to Work
Error Requiring Pg Under Rvm with Postgres.App
Ruby Sequel: Array Returned by Query Is Being Returned as a String Object, Not an Array Object