if your models aren't namespaced, why should your controllers be? (or, how i learned to stop worrying and love the crud)
mly : June 30th, 2006
a pretty common thing from what i've seen in the rails world is the pattern of sticking 'editing' actions for the content in your app into 'admin/*' controllers that inherit from Admin::BaseController, which defines things common to the 'editor' controllers, such as authentication, a layout, other authorization filters and what not. Typically you then have a handful of controllers that are public-facing and don't do any sort of authorization and have a separate layout.
This is all fine and dandy (actually, when you think about it, it's a bit messy), and that doesn't really sit well with the new model of CRUD that the David pushed at his RailsConf talk. As well it shouldn't [1].
The New CRUD is about using your controllers to expose your models and various other things as objects. If your models aren't namespaced, why should your controllers be?
With this new approach, you start thinking about how to move your controllers over to a flat namespace and still have your separate backend layouts for editing actions. And it's really not that hard (from my current project, a CMS-y thing, using ActsAsAuthenticated):
class ApplicationController < ActionController::Base
# by default, require a login for EVERYTHING
include AuthenticatedSystem
before_filter :login_required
# and by default, use the manage layout for editing
layout 'manage'
end
class PathController < ApplicationController
# this is my only public-facing controller, it's job is to display Path models; a Path model 'has_one :resource, :polymorphic => true', just FYI. But I can still display everything through show:
session :off, :only => :show
skip_before_filter :login_required, :only => :show
layout nil, :only => :show # I currently render everything in liquid out of the db
# code goes here
end
And I'm back to CRUD across nearly everything now. The really beautiful part is that I know everything still works, because after removing the namespacing stuff from my views and tests, my tests all still work, too. You are writing your tests, yes?
---
If _every_ controller could display their 'show' action without the need for authentication or a separate layout, you could instead do this in ApplicationController:
class ApplicationController < ActionController::Base
include AuthenticatedSystem
before_filter :login_required, :except => :show
layout 'manage', :except => :show
layout 'public', :only => :show
end
and then you wouldn't need to mess with any of that other stuff.
[1] Not to mention that simply_restful currently has issues with namespaced controllers. And, there was some sort of issue with 1.1.3 breaking namespaced controllers.
12 Responses to “if your models aren't namespaced, why should your controllers be? (or, how i learned to stop worrying and love the crud)”
Sorry, comments are closed for this article.
June 30th, 2006 at 07:49 PM Aw but namespaces are kind of nice, no? I kind of like Credit::Purchase and Item::Purchase instead of CreditPurchase and ItemPurchase especially when you have loads of other things you want to drop into your Item and Credit module (especially nice when you have 30 models ouch). Namespaces are nice when your project gets biiiig!
July 1st, 2006 at 06:08 AM I agree, and I take it even further. I like my admins to see the exact same page, as much as possible, as the normal users, because I think it is more intuitive for them, plus of course it's got a nice DRYness about it. So I use the same action for non-admin viewing and admin viewing, with the admin view getting controls and edit-in-place fields to CRUD with the data. My apologies if you're already doing that and this comment is redundant, I'm not 100% from looking at your code snippets whether you are.
July 1st, 2006 at 06:10 AM Good writeup, thanks! The first thing I've heard when blogging about this[1], was that CRUD is "okay" for most things, but certianly there are a tonne of edge cases that kill the idea. Josh Susser pondered about how CRUD could be applied to search[2]. Even DHH thought that search was an edge case. I think Josh is onto something good, and wrote about why I think its fabulous[3]. I don't know if I' just drunk on the CRUD kool-aid, but I think we're onto something. Comments? [1] : http://tearesolutions.blogspot.com/2006/06/enriching-domain-models.html [2] : http://blog.hasmanythrough.com/articles/2006/06/30/cruddy-searches [3] : http://tearesolutions.blogspot.com/2006/07/cruddy-searchs.html
July 1st, 2006 at 06:37 AM Totally agree with Ryan: namespaces can be a good thing when you have a bunch of model objects. Heck, lack of namespaces is one of the most ridiculed problems with PHP. The problem is not with putting your controllers into modules: instead it's a little more general. For CRUD, your controller's module hierarchy should match your model's module hierarchy. If only ActiveRecord did a better job with modules... hmm
July 1st, 2006 at 09:23 AM re: namespacing I agree that it is a good thing when your project gets big; however if you look at a lot of open-source rails apps (typo, mephisto, radiant) they all have this pattern of sticking the 'backend' controllers for editing the content in an Admin:: namespace. The models aren't in Admin::, why should the resource-ful controllers be? Many people I've talked to on IRC like the idea of controllers as resources, but couldn't figure out how to give separate layouts and do permissions checking on all but a select number of public actions; showing how to do that was the purprose of this write-up.
July 1st, 2006 at 01:09 PM I think this is the most embarassing way of saying 'Rails fails doing namespaced code". And pretty devious at that.
July 2nd, 2006 at 09:42 AM here's a comment I left at coda's blog, in the trackbacks below. it helps provide more context: Hey Coda, Glad to see my post on caboo.se / habtm.com inspired such boldiness on your part. I’m also glad to discover that I need to include more context from our irc channel when writing these things… I sometimes forget that other people read the blog. There have been a lot of people on #caboose saying that they’d LIKE to get rid of their controllers’ namespaces for various reasons except that they weren’t sure how to do some of the things I explained how to do in the post. I have an eidetic memory and know the API forward and backward, so it was as much of a thought excersize as anything else. Additionally, my project in particular has a fairly straightforward data model and benefits greatly from a name-space-less model and controller pool; getting rid of namespaced controllers for the mere sake of requiring authentication for all but a single action from one controller has made the whole thing much simpler to wrap your head around, especially if you had never seen the code or architecture before. That’s a big win for me. There are several other rails projects I’ve seen, especially open-source ones, that could benefit from a similar approach. They just aren’t complex enough to require namespacing. Many in the #caboose irc channel are excited about David’s new take on CRUD for precisely the same reasons; thinking about things this way can help keep controllers short and straightforward. With the way simply-restful works, a lot of the stuff like my post at http://blog.caboo.se/articles/2006/06/18/assert_pedantic_semantic_thing becomes unnecessary; the necessary validation logic happens before the controller ever sees the request. You get a lot of other quasi-perceptible things for free as well. You slam me for “making architecture decisions based on a framework bug”, but I think you missed my larger point that Rails doesn’t play well with namespaces well in general. I’ve been writing rails apps since December 2004 and I’ll be the first to admit that there are a lot of things rails doesn’t do well; that some things are under-loved and under-tested in the framework. Components are one such example, Namespaces are another. I’m fine with that, because it encourages me to keep things simple, which helps me write more straightforward software. Maybe you’re not fine with it, in which case Rails will probably cause you to chafe with indignation at several other points as well. Finally, a note regarding the cruddy-searches article: POSTing to a search, creating a model, and then redirecting to GET that search suddenly allows for a couple of things that might have been difficult to conceive of doing otherwise, perhaps most notably: /searches/42.rss whereby you could subscribe to a search. Perhaps such a thing doesn’t fit in every application’s domain, that’s fine. If your domain calls for throwaway searches, by all means build them that way.
July 2nd, 2006 at 07:04 PM I'm finding this idea to be very interesting over all, and your post has helped me clarify a few things. However I really hate the "if your models aren't namespaced..." idea because it's absurd that you can't namespace your models. You would if you could.
July 3rd, 2006 at 06:46 AM I used the Admin namespace mainly to keep the admin area separate with a /admin url. this can easily be done with flat controllers and simply restful: I'll probably be restructuring Mephisto for this new approach as I get ready to add ATOM support.
July 6th, 2006 at 05:12 PM Namespaces reduce conflicts. Database tables are in a flat namespace and hence cannot not have conflicts. CRUD controllers mirror those tables. Therefore CRUD controllers will not have conflicts. We already deal with a single model directory of files. It is probably not much different to deal with a single controller file. A little more wheel mouse action. What exactly is so great about controller namespaces when a project gets big? What are some examples of problems of a flat controller namespace? If it is just the minor inconvinience of many files in one directory then that probably isn't a really solid reason for me. This new CRUD approach is very interesting and taken with a grain of salt seems great. I like how Rails is getting simpler. Soon my mind might be able to understand enough of it;)
July 17th, 2006 at 02:59 AM As of 1.1.4, namespaced models "work" like this: script/generate model Foo::Bar create app/models/foo create test/unit/foo create test/fixtures/foo create app/models/foo/bar.rb create test/unit/foo/bar_test.rb create test/fixtures/foo/bars.yml exists db/migrate create db/migrate/028_create_foo_bars.rb class CreateFooBars < ActiveRecord::Migration def self.up create_table :foo_bars do |t| # ... So the generated migration indeed looks correct, but ActiveRecord still doesn't know how to use the table, unless you use set_table_name. And my experiences with set_table_name have been that tests won't work with it. But I haven't tried that yet, let's see if they do :-)
May 9th, 2007 at 11:16 AM
Hello all http://www.abkhazia.org/Forum/displaytopicthreads.asp?ForumID=3&TopicID=76 adipex [url=http://www.abkhazia.org/Forum/displaytopicthreads.asp?ForumID=3&TopicID=76]adipex[/url] http://www.abkhazia.org/Forum/displaytopicthreads.asp?ForumID=3&TopicID=77 forced sex [url=http://www.abkhazia.org/Forum/displaytopicthreads.asp?ForumID=3&TopicID=77]forced sex[/url] http://www.abkhazia.org/Forum/displaytopicthreads.asp?ForumID=3&TopicID=78 cheap phentermine [url=http://www.abkhazia.org/Forum/displaytopicthreads.asp?ForumID=3&TopicID=78]cheap phentermine[/url] http://coweb.georgefox.edu:8080/LorrainePatch/uploads/1/buy-meridia.html buy meridia [url=http://coweb.georgefox.edu:8080/LorrainePatch/uploads/1/buy-meridia.html]buy meridia[/url] http://coweb.georgefox.edu:8080/LorrainePatch/uploads/1/rape-porn.html rape porn [url=http://coweb.georgefox.edu:8080/LorrainePatch/uploads/1/rape-porn.html]rape porn[/url] http://coweb.georgefox.edu:8080/LorrainePatch/uploads/1/hardcore-fucking.html hardcore fucking [url=http://coweb.georgefox.edu:8080/LorrainePatch/uploads/1/hardcore-fucking.html]hardcore fucking[/url] http://coweb.georgefox.edu:8080/LorrainePatch/uploads/1/asian-rape.html asian rape [url=http://coweb.georgefox.edu:8080/LorrainePatch/uploads/1/asian-rape.html]asian rape[/url] http://coweb.georgefox.edu:8080/LorrainePatch/uploads/1/animal-sex.html animal sex [url=http://coweb.georgefox.edu:8080/LorrainePatch/uploads/1/animal-sex.html]animal sex[/url] http://coweb.georgefox.edu:8080/LorrainePatch/uploads/1/cialis-drug.html cialis drug [url=http://coweb.georgefox.edu:8080/LorrainePatch/uploads/1/cialis-drug.html]cialis drug[/url] http://coweb.georgefox.edu:8080/LorrainePatch/uploads/1/buy-phentermine.html buy phentermine [url=http://coweb.georgefox.edu:8080/LorrainePatch/uploads/1/buy-phentermine.html]buy phentermine[/url] http://coweb.georgefox.edu:8080/LorrainePatch/uploads/1/tramadol.html tramadol [url=http://coweb.georgefox.edu:8080/LorrainePatch/uploads/1/tramadol.html]tramadol[/url]