Dynamic-Scaffold-Resource is dead, long live RestController 4

Posted by Tim Connor Tue, 03 Apr 2007 18:39:00 GMT

I got tired of the complexities of my plug-in solution to DRYing up the shared code in all my Restful controllers, and scaffolding gets no love from core. But after a little while I got almost as tired of having the same 7 methods repeated throughout my code base. Thus a new simpler project is born: RestContoller.

Instead of scaffolding your views (which the core team is right about – those should diverge widely to fit the UI needs) or adding tests for you, it just gives you a main rest controller to inherit from that has the 7 basic actions (index, show, new, edit, create, update, and destroy). I was also able to simply further and drop the giant block eval, by looking over Jake Howerto’s CRUDController and borrowing a technique or two (such as the use of instance_variable_set). This should make the code easier to follow, customize, and also more performant.

You can just do a vanilla checkout from Google Code, and then inherit from that.


svn checkout http://restcontroller.googlecode.com/svn/trunk/ app/controllers/rest
class YourModelController < REST::RestController

but with this new approach it’s much more natural to customize per project. You can just go ahead and grab the file, save a local copy, check it into your own source control, and do with it as you will. For instance, if all of your resources have a public facing front, but the rest should be restricted, just add something like this (as well as the appropriate function in your application.rb)
before_filter :require_login, :except =>[:show, :index]

Comments

Leave a comment

  1. Avatar
    rrodrigu3z@gmail.com 2 days later:

    Hi! Excellent Job!. I was working on a similar code a couple of days ago.. I will share it soon. Here is an excerpt of my CRUDController, I’m using the plugins GLoc and paginating_find and the private methods are in a Module (MetodosPrivados). Finally I use shared views if defaults do not exists on the views/controllername directory.
    Sorry about my english… I’m Venezuelan.. Saludos!

    http://pastie.caboo.se/52215

  2. Avatar
    Tim Connor 3 days later:

    Hey, rodriguez, thanks for sharing. I put your code in a pastie so it didn’t take up pages with scrolling.

    I did all sort of complexities with finding scaffolded templates and stuff, in my original plugin, this was an attempt to get back to basics. Give me an update when you have it up somewhere, and I’ll link to it as an alternative, from my project.

    You should check out some of my most recent changes. I have added a options hash, so you can just pass in template, to a call to super, if you want. Doing it that way makes it easy to override instance variables, too. I’ll blog about them when I get them more concrete and finalized.

    def index
      @page_title = 'Overriden title'
      super :template => 'custom_template'
    end
    
  3. Avatar
    Ed Allen 4 months later:

    I’ve been using your RestController for awhile in one project that I’ve been learning to do REST in. I started it a few months ago and then set it aside awhile. Picked it back up about a week ago and promptly ran into a bug in the older version of your RestController I have in my project. I tracked it down this evening. I just downloaded the new version to check and it looks like the bug is still there.

    The old current_model method and new resource_model method both do

    Object.const_get resource_name.classify

    This works most of the time but chokes on certain names where the singular name looks plural to the classify method so it strips off the s at the end. Classify expects to get a table (plural) name. For example, see http://www.akelos.com/docs/inflector/default/Inflector.html#classify

    “darts”.classify —> “Dart”

    “dart”.classify —> “Dart”

    “passes”.classify —> “Pass”

    “pass”.classify —> “Pas”

    “class”.classify —> “Clas”

    I got it working on the problem model in my project (CharacterClass for a geeky D&D thing) by changing to

    def current_model



    Object.const_get resources_name.classify

    end

  4. Avatar
    Tim Connor 6 months later:

    Thanks, Ed. I’ll have to look into that one of these days, since I’m using it at my new job.

Comments