how do I make the URL's in Ruby on Rails SEO friendly knowing a @vendor.name?

前端 未结 7 1773
你的背包
你的背包 2021-02-04 12:06

My application is in RoR

I have an action/view called showsummary where the ID has been passed into the URL, and the controller has used that to instantiate @vendor wher

相关标签:
7条回答
  • 2021-02-04 12:18

    Ryan Bates has a great screencast on this very subject.

    Basically you overload the to_param method in the Vendor model.

       def to_param
         permalink
       end
    

    Then when you look up the resource in your controller you do something like this:

       @vender = Vender.find_by_name(params[:id])
    

    But the problem with this is that you'll have to make sure that the vendors' names are unique. If they can't be then do the other solution that Ryan suggests where he prepends the the id to the name and then parses the resulting uri to find the item id.

    0 讨论(0)
  • 2021-02-04 12:20

    I thought I'd mention String#parameterize, as a supplement to the tagged answer.

    def to_param
      "#{id}-#{name.parameterize}"
    end
    

    It'll filter out hyphenated characters, replace spaces with dashes etc.

    0 讨论(0)
  • 2021-02-04 12:21

    Friendly ID http://github.com/norman/friendly_id/blob/26b373414eba639a773e61ac595bb9c1424f6c0b/README.rdoc

    0 讨论(0)
  • 2021-02-04 12:22

    You do this by modifying the routes that are used to access those URL's and changing them to use :name, rather than :id. This will probably mean that you have to write the routes yourself rather than relying on resources.

    For instance add this to the routes.rb file:

    map.with_options :controller => "vendor" do |vendor|
      vendor.connect "/vendor/:name", :action => "show"
      # more routes here for update, delete, new, etc as required
    end
    

    The other change that will be required is that now you'll have to find the vendor object in the database by the name not the id, so:

    @vendor = Vendor.find_by_name(params[:name])
    

    Internally (at least to my knowledge/experimentation) whatever parameter name is not specified in the URL part of the route (i.e. not within the "/Controller/Action/:id" part of it) is tacked on to the end as a parameter.

    0 讨论(0)
  • 2021-02-04 12:24

    Take a look also at this quck start to SEO for Rails

    0 讨论(0)
  • 2021-02-04 12:33

    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.

    0 讨论(0)
提交回复
热议问题