devroom.io/content/posts/2007-04-12-rails-resources-and-permalinks.md

97 lines
3.2 KiB
Markdown
Raw Normal View History

2015-03-26 11:28:08 +00:00
+++
date = "2007-04-12"
title = "Rails, Resources and Permalinks"
tags = ["General", "RubyOnRails", "Features"]
slug = "rails-resources-and-permalinks"
2017-09-11 12:20:15 +00:00
description = "How to add permalinks to your resources."
2015-03-26 11:28:08 +00:00
+++
There has been quite a bit of discussion about creating permalinks with a rails resource. In this article I will show you how to create permalinks for a resource named 'pages' without giving up on any of the resource goodness!
2017-03-20 15:35:19 +00:00
2015-03-26 11:28:08 +00:00
Before I start I'll presume you have a page scaffold_resource setup in your rails application. Make sure you have at least the following fields in your page model:
2017-03-20 15:35:19 +00:00
``` ruby
t.column :title, :string
2015-03-26 11:28:08 +00:00
t.column :permalink, :string
2017-03-20 15:35:19 +00:00
t.column :content, :text
```
2015-03-26 11:28:08 +00:00
Okay, what you want is the permalink_fu plugin. This plugin greatly simplifies the act of generating a permalink from a title. Install it first:
2017-03-20 15:35:19 +00:00
``` shell
cd railsapp
./script/plugin install http://svn.techno-weenie.net/projects/plugins/permalink_fu/
```
2015-03-26 11:28:08 +00:00
In your Page model you may now add the following line. This line will generate a permalink in the permalink attribute automatically, so you don't have to show the permalink field in any forms.
2017-03-20 15:35:19 +00:00
``` ruby
has_permalink :title
```
2015-03-26 11:28:08 +00:00
That's it for generating the appropriate permalink string in your database.
Rails goodness has already provided you with the basic RESTful routes:
2017-03-20 15:35:19 +00:00
2015-03-26 11:28:08 +00:00
<ul>
<li>/pages</li>
<li>/pages/123</li>
<li>/pages/new</li>
<li>/pages/123;edit</li>
</ul>
2017-03-20 15:35:19 +00:00
2015-03-26 11:28:08 +00:00
But what you really want, is something like:
2017-03-20 15:35:19 +00:00
2015-03-26 11:28:08 +00:00
<ul>
<li>/pages/perma-link-here</li>
</ul>
2017-03-20 15:35:19 +00:00
2015-03-26 11:28:08 +00:00
Notice that the permalink url is only a GET request and should not be used for editing or updating the page in question.
Since using any other identifier than :id in a resource is madness, I create two new routes that will allow me to access permalinked pages. Not only that, but I do maintain the format option. Basically this means that you get three routes:
2017-03-20 15:35:19 +00:00
2015-03-26 11:28:08 +00:00
<ul>
<li>/page/perma-link-here</li>
<li>/page/perma-link-here.html</li>
<li>/page/perma-link-here.xml</li>
</ul>
2017-03-20 15:35:19 +00:00
2015-03-26 11:28:08 +00:00
Notice that I removed the 's' from 'pages' here. This is to avoid confusion with the resource 'pages'. But more on that later.
Now in config/routes.rb add the following two lines:
2017-03-20 15:35:19 +00:00
``` ruby
map.permalink 'page/:permalink', :controller => 'pages', :action => 'permalink'
map.connect 'page/:permalink.:format', :controller => 'pages', :action => 'permalink', :format => nil
```
2015-03-26 11:28:08 +00:00
The first line adds a named route to an action named 'permalink' in your PagesController. This gives you the ability to add peralink links easily:
2017-03-20 15:35:19 +00:00
``` ruby
permalink_url(@page.permalink)
```
2015-03-26 11:28:08 +00:00
The second link is unnamed, and allows you to specify a format like HTML or XML.
The permalink action looks like this:
2017-03-20 15:35:19 +00:00
``` ruby
# GET /page/perma-link
2015-03-26 11:28:08 +00:00
# GET /page/permal-link.xml
def permalink
@page = Page.find_by_permalink(params[:permalink])
respond_to do |format|
format.html { render :action => 'show' }
format.xml { render :xml => @page.to_xml }
end
2017-03-20 15:35:19 +00:00
end
```
2015-03-26 11:28:08 +00:00
This special permalink action uses the same 'show' view as your resource.
If you want to maintain the 'pages' part of the URL, that's possible. You'll have to write a condition that makes sure that the :permalink parameter is a string an not an integer (ID). This article does not cover this.
You may now use permalinks for your pages! Congratulations.