<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>The Life Of A Radar &#187; namespacing</title>
	<atom:link href="http://ryanbigg.com/tag/namespacing/feed/" rel="self" type="application/rss+xml" />
	<link>http://ryanbigg.com</link>
	<description>Life &#38; Everything Else</description>
	<lastBuildDate>Mon, 30 Aug 2010 11:30:39 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Administration Namespacing</title>
		<link>http://ryanbigg.com/2008/03/administration-namespacing/</link>
		<comments>http://ryanbigg.com/2008/03/administration-namespacing/#comments</comments>
		<pubDate>Sun, 16 Mar 2008 00:49:58 +0000</pubDate>
		<dc:creator>Radar</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[namespacing]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://frozenplague.net/2008/03/16/administration-namespacing/</guid>
		<description><![CDATA[A while after completing work at SeaLink, Tom asked me about my forum hobby project and why it wasn&#8217;t working. This led to me working on it for a few days and getting it all up to scratch again, and this involved moving it over to Rails 2.0 (that&#8217;s how long I hadn&#8217;t worked on [...]]]></description>
			<content:encoded><![CDATA[<p>A while after completing work at SeaLink, Tom asked me about my forum hobby project and why it wasn&#8217;t working. This led to me working on it for a few days and getting it all up to scratch again, and this involved moving it over to Rails 2.0 (that&#8217;s how long I hadn&#8217;t worked on it for), and using the awesomeness that is namespacing.</p>

<p>Namespacing is where you have some controllers in a separate area of your site. In my example, I have an admin folder in <span class="term">app/controllers</span> which contains all the controllers for the administration section of my site, and all the relevant actions. Just inside the <span class="term">app/controllers</span> directory, I have the other controllers which do all the basic stuff such as showing forums, basically anything a standard user can do.</p>

<p>It seems to be a fairly common question asked in places, so I figured if I sat down and wrote this, I would have something to send to people, much like my <a href="http://frozenplague.net/2008/01/06/restful-routing-an-overview/">Restful Routes tutorial</a>, which ideally should&#8217;ve covered namespacing too.</p>

<p>First of all we&#8217;re going to create our namespace. To do that, we open up <span class="term">config/routes.rb</span> and specify our namespace:
<pre lang="rails">map.namespace(:admin) do |admin|
admin.resources :forums, :topics, :posts
end</pre>
Now what this does is defines some routes for us. If you&#8217;ve seen <span class="term">map.resources</span> you&#8217;ll know that this defines routes for us, for example doing map.resources :forums will define methods such as <span class="term">forums<em>path</span> which is the same as <span class="term">{ :controller => &#8220;forums&#8221;, :action => &#8220;index&#8221; }</span> and <span class="term">forum</em>path(@forum) </span>which is the same as <span class="term">{ :controller => &#8220;forums&#8221;, :action => &#8220;show&#8221;, :id => @forum.id }</span>. These methods really are lifesavers and save you a hell of a lot of typing. The routes defined by this namespace method however are prefixed with whatever argument you pass it, in this case we&#8217;ve passed it <span class="term">:admin</span> so it&#8217;s going to give us routes like <span class="term">admin<em>forums</em>path</span>, which is the same as <span class="term">{ :controller = > &#8220;admin/forums&#8221;, :action => &#8220;index&#8221; }, </span>and as you can see again saves us a lot of typing.</p>

<p>Now that we have our namespace, we can create our subfolders. These subfolders are placed in <span class="term">app/controllers </span>and <span class="term">app/views </span>and are given the same name as the namespace, admin. So go ahead and do that now. In <span class="term">app/controllers/admin </span>is where we place our controllers. As an example, here&#8217;s what my forums controller&#8217;s edit and update actions look like:
<pre lang="rails">class Admin::ForumsController &lt; Admin::ApplicationController
  before<em>filter :store</em>location, :only => [:index, :show]
  def edit
    @forum = Forum.find(params[:id]) 
    @forums = Forum.find(:all, :order => "title") - [@forum] - @forum.descendants
  end</p>

<p>def update 
    @forum = Forum.find(params[:id])
    if @forum.update<em>attributes(params[:forum])
      flash[:notice] = "Forum has been updated."
      redirect
    else
      flash[:notice] = "Forum has not been updated."
      render :action => "edit"
    end
  end
end</pre>
What I really want to show you in here is only the first line the class is defined as Admin::ForumsController, which shows that we&#8217;re namespacing it. We don&#8217;t have to define the Admin prefix anywhere. What we do have to define however is our non-existant Admin::ApplicationController. In my code, I&#8217;ve defined my own Admin::ApplicationController as a means of calling methods that should be called before all admin actions, such as my <span class="term">non</em>admin<em>redirect</span> method, which is defined in <span class="term">lib/authenticated</em>system.rb</span> and goes something like this:
<pre lang="rails">  def non<em>admin</em>redirect
    if !is<em>admin?
      flash[:notice] = "You need to be an admin to do that."
      redirect</em>back<em>or</em>default(:controller => "/accounts", :action => "login")
    end
  end</pre>
To define your <span class="term">Admin::ApplicationController</span>, make a file in <span class="term">app/controllers/admin</span> called <span class="term">application<em>controller.rb</span>. Even though the main application controller is defined as <span class="term">application.rb</span> in <span class="term">app/controllers</span>, that file is automatically loaded by Rails. If we named our application</em>controller to just application.rb, it would not be automatically loaded because Rails only looks for application.rb and files ending in <em>controller.rb in the app/controllers directory, so we name ours application</em>controller.rb so it plays nice with Rails.</p>

<p>In here we define our class, layout and helper:
<pre lang="rails">class Admin::ApplicationController &lt; ApplicationController
  layout "admin"
  helper "admin"
  before<em>filter :non</em>admin<em>redirect
end</pre>
I&#8217;ve defined a new layout here because my admin layout is different to my main layout, but still includes some elements from it (thanks to nested</em>layouts)</p>

<p>The before_filter is triggered before every action in the admin controller to make sure it&#8217;s an admin doing the action rather than a standard user.</p>

<p>And that&#8217;s all there is to it, really. It&#8217;s all pretty simple. Now all you&#8217;ve gotta do is generate your views. Remember to place them in app/views/admin/the<em>controller&#8217;s</em>name, otherwise you&#8217;ll run into problems.</p>

<p>It seems I forgot to mention how it&#8217;s supposed to work when you&#8217;re calling the method to go to the namespaced path, well that&#8217;s simple.  If you have a forum you would like to edit, the correct method is <span class="term">edit<em>admin</em>forum<em>path(forum</em>object)</span>, because you want to edit, in the namespace of admin, a certain forum. For paths not requiring a prefix, such as the show and index actions, they are <span class="term">admin<em>forum</em>path(forum<em>object)</span> and admin</em>forums_path respectively.</p>

<p>For an action such as an update action, it would be <span class="term">admin<em>forum</em>path(forum<em>object)</span> with a <span class="term">:method => :put</span> option specified in whatever you&#8217;re using. Usually you won&#8217;t have to do this, because the form</em>for helper would do it for you, but in some cases you might have to.</p>
]]></content:encoded>
			<wfw:commentRss>http://ryanbigg.com/2008/03/administration-namespacing/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>
