========================================Creating a Global REST Controller ======================================== Let''s imagine that you have an application that houses close to 400 controllers. Each of these controllers accesses a specific model that contains normalized data. While there are a lot of tricks you can perform for normalization, let''s assume that after you further normalize and consolidate databases you still have 300 controllers left over. Of these 300 controllers, half of them are composed of normal REST methods, and the other half are comprised of normal REST methods and special methods which perform specific actions. This means that each of those controllers at a bare minimum could have close to 80 lines of code. Everyone talks about thin controllers. I''m going to show you a way to create a Global REST controller that will make most if not all of your controllers very thin. http://gist.github.com/280611 Take a look at the code above and look closely at the Global REST Controller. Let''s pretend that you have a controller that manages pages, ie. a Pages Controller. It''s comprised of only index, new, edit, show, create, update, and destroy. No other actions. By implementing a Global REST controller, you could place this in your pages controller: class PagesController < GlobalRestController end .. and that''s all you need (2 lines of code) In your index.html.erb view you would replace one instance variable @pages with @objects and you are done. Now then, going back to the old scenario I posted above, you could effectively take 150 controllers with say 78 lines of code and reduce 11,700 lines of code down to .. 300. What could you do with your other 150 controllers? class SomeOtherController < GlobalRestController def some_custom_action .. etc. .. etc. end def some_other_custom_action .. etc. .. etc. end end Your custom actions would be listed but you would automatically inherit the other 7 rest methods automatically. No extra code needed. What if you want to overwrite one of the REST methods with a custom REST method of your own? class SomeOtherController < GlobalRestController def index @pages = Page.find(:all, :conditions => ''parent_id IS NOT NULL'') respond_to do |format| format.html format.xml { render :xml => @pages } end end end You just simply place the REST method into your controller and it still picks up the other 6 REST methods. You then keep the index.html.erb page intact without @objects changes and you are done. How well does this work? I currently run a football statistics site that houses 75 controllers and (66 of them) are part of a Global REST Controller mechanism. I have had no issues whatsoever using it. I hope this tutorial helps someone out. If you liked this tutorial, you can check out a very lengthy tutorial I wrote yesterday on mailers and observers here: http://www.ruby-forum.com/topic/202316 Take care. -- Posted via http://www.ruby-forum.com/. -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
In a follow-up on your edit.html.erb and new.html.erb you could use something similar: Replace @page with @object. I''ve added a partial and a couple of example forms for these as well in the gist posted above. -- Posted via http://www.ruby-forum.com/. -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Very cool. I''m glad to hear it is working out so well for you Alpha... -- Posted via http://www.ruby-forum.com/. -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Interesting tutorial. Thanks. I found there are a couple of little problems. First, your index view code has some extra closing round brackets, and then the destroy action redirects back to the deleted object. I took a little while to fork and update the controller code. Also made it a bit more DRY: http://gist.github.com/280670 One question though, why wouldn''t you use, for example, inherited_resources plugin for this purpose? - Aleksey -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
On Jan 19, 12:43 am, Aleksey Gureiev <spyro...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Interesting tutorial. Thanks. > > I found there are a couple of little problems. First, your index view > code has some extra closing round brackets, and then the destroy > action redirects back to the deleted object. I took a little while to > fork and update the controller code. Also made it a bit more DRY: > > http://gist.github.com/280670 > > One question though, why wouldn''t you use, for example, > inherited_resources plugin for this purpose? > > - AlekseyI don''t wanna speak for Alpha Blue, but straight plain inheritance is a simple answer to a common problem... -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Marnen Laibow-Koser
2010-Jan-19 08:00 UTC
Re: Tutorial - Creating a Global REST Controller
Alpha Blue wrote:> ========================================> Creating a Global REST Controller > ========================================> > Let''s imagine that you have an application that houses close to 400 > controllers. Each of these controllers accesses a specific model that > contains normalized data. While there are a lot of tricks you can > perform for normalization, let''s assume that after you further normalize > and consolidate databases you still have 300 controllers left over.Why would you ever have that many controllers in the first place? That makes no sense.> > Of these 300 controllers, half of them are composed of normal REST > methods, and the other half are comprised of normal REST methods and > special methods which perform specific actions. > > This means that each of those controllers at a bare minimum could have > close to 80 lines of code.What? No. An 80-line controller means you have too much logic in the controller and not enough in the model.> > Everyone talks about thin controllers. I''m going to show you a way to > create a Global REST controller that will make most if not all of your > controllers very thin.Why not just use make_resourceful? Best, -- Marnen Laibow-Koser http://www.marnen.org marnen-sbuyVjPbboAdnm+yROfE0A@public.gmane.org -- Posted via http://www.ruby-forum.com/. --0022158df84fc113d7047d7fdd08 Content-Type: text/plain; charset=ISO-8859-1 -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en. --0022158df84fc113d7047d7fdd08--
It seems like to create 300 ReST controllers via Rails Scaffolding or make_resourceful, one would need to type all the specs for all the tables into the Rails Scaffolding generator. If I am reading correctly, one could use Global Rest Controllers on existing tables, and those controllers would read the tables structures for themselves. I work a lot with legacy tables, so I would dislike typing the structure into the Rails Generator all the time. I don''t do that: I use home-brew Scaffolding Generators that read the table structure, like the old pre-Restful Rails scaffolding. Anyway, could that be one difference? Ron On Jan 19, 3:00 am, Marnen Laibow-Koser <li...-fsXkhYbjdPsEEoCn2XhGlw@public.gmane.org> wrote:> Alpha Blue wrote: > > ========================================> > Creating a Global REST Controller > > ========================================> > > Let''s imagine that you have an application that houses close to 400 > > controllers. Each of these controllers accesses a specific model that > > contains normalized data. While there are a lot of tricks you can > > perform for normalization, let''s assume that after you further normalize > > and consolidate databases you still have 300 controllers left over. > > Why would you ever have that many controllers in the first place? That > makes no sense. > > > > > Of these 300 controllers, half of them are composed of normal REST > > methods, and the other half are comprised of normal REST methods and > > special methods which perform specific actions. > > > This means that each of those controllers at a bare minimum could have > > close to 80 lines of code. > > What? No. An 80-line controller means you have too much logic in the > controller and not enough in the model. > > > > > Everyone talks about thin controllers. I''m going to show you a way to > > create a Global REST controller that will make most if not all of your > > controllers very thin. > > Why not just use make_resourceful? > > Best, > -- > Marnen Laibow-Koserhttp://www.marnen.org > mar...-sbuyVjPbboAdnm+yROfE0A@public.gmane.org > -- > Posted viahttp://www.ruby-forum.com/.-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Aleksey Gureiev wrote:> Interesting tutorial. Thanks. > > I found there are a couple of little problems. First, your index view > code has some extra closing round brackets, and then the destroy > action redirects back to the deleted object. I took a little while to > fork and update the controller code. Also made it a bit more DRY: > > http://gist.github.com/280670 > > One question though, why wouldn''t you use, for example, > inherited_resources plugin for this purpose? > > - AlekseyThanks for that Aleksey, I had copied and pasted from an older controller that was using not so polished code. I very rarely use plugins in my app. I don''t like to use code that I can''t control myself. I would rather find a plugin that is suitable, dive into the code, learn from it, and create my own modified plugins. This is just a very simple tutorial outlining to some newer folk how they can create an inheritance template for their controllers. I have my own private inheritance template for my models, which works equally well.> Marnen Laibow-Koser > Why would you ever have that many controllers in the first place? That > makes no sense.Your statement doesn''t make any sense. I''ll give you one answer before you throw out the assumptions once again mate. You really should stop doing that. My one application is comprised of: 4 separately run applications tied together on different servers. -- Posted via http://www.ruby-forum.com/. -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Marnen Laibow-Koser
2010-Jan-19 14:58 UTC
Re: Tutorial - Creating a Global REST Controller
Alpha Blue wrote:> Aleksey Gureiev wrote: >> Interesting tutorial. Thanks. >> >> I found there are a couple of little problems. First, your index view >> code has some extra closing round brackets, and then the destroy >> action redirects back to the deleted object. I took a little while to >> fork and update the controller code. Also made it a bit more DRY: >> >> http://gist.github.com/280670 >> >> One question though, why wouldn''t you use, for example, >> inherited_resources plugin for this purpose? >> >> - Aleksey > > > Thanks for that Aleksey, I had copied and pasted from an older > controller that was using not so polished code. > > I very rarely use plugins in my app. I don''t like to use code that I > can''t control myself. I would rather find a plugin that is suitable, > dive into the code, learn from it, and create my own modified plugins.http://c2.com/cgi/wiki?NotInventedHere I have the opposite philosophy. If someone has already written something suitable, I see little reason to duplicate their effort. Extend it, sure. Write something that''s a better fit for me, sure. But by just saying "I don''t like plugins", you''re making yourself a lot of extra work for no good reason.> > This is just a very simple tutorial outlining to some newer folk how > they can create an inheritance template for their controllers. > > I have my own private inheritance template for my models, which works > equally well.Sure.> >> Marnen Laibow-Koser >> Why would you ever have that many controllers in the first place? That >> makes no sense. > > Your statement doesn''t make any sense.Of course it does. No matter how many models your app has, I can''t see why a well-designed app would ever need to expose 300 different types of resource -- which is essentially what controllers are about.> I''ll give you one answer before > you throw out the assumptions once again mate. You really should stop > doing that.I''m not assuming anything in particular, so this is not relevant.> My one application is comprised of: > > 4 separately run applications tied together on different servers.Then it isn''t one application. Or it''s one application run clustered. In neither case do I see this making the slightest difference to the number of controllers. See, the number of controllers is a UI issue. No matter how many types of object you''re dealing with under the hood, if the user has to navigate among 300 controllers (which, after all, are generally the user-facing part of the app), then in 99 cases out of 100, I''d say you need to refactor the UI or split up the app. Best, -- Marnen Laibow-Koser http://www.marnen.org marnen-sbuyVjPbboAdnm+yROfE0A@public.gmane.org -- Posted via http://www.ruby-forum.com/. --0015175cd162c1246b047d85b5fe Content-Type: text/plain; charset=ISO-8859-1 -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en. --0015175cd162c1246b047d85b5fe--
On Jan 19, 2:58 pm, Marnen Laibow-Koser <li...-fsXkhYbjdPsEEoCn2XhGlw@public.gmane.org> wrote:> > I very rarely use plugins in my app. I don''t like to use code that I > > can''t control myself. I would rather find a plugin that is suitable, > > dive into the code, learn from it, and create my own modified plugins. > > http://c2.com/cgi/wiki?NotInventedHere > > I have the opposite philosophy. If someone has already written > something suitable, I see little reason to duplicate their effort. > Extend it, sure. Write something that''s a better fit for me, sure.I find it a difficult one to call - while the above is true it''s horrible find come rails upgrade time that the author has abandoned the project. Lots of rails plugins are small one man things - I would certainly hesitate to use a plugin unless either it has sufficient backing/momentum that I can trust it will stay around or I understand it enough that I could rewrite it if I had to.> See, the number of controllers is a UI issue. No matter how many types > of object you''re dealing with under the hood, if the user has to > navigate among 300 controllers (which, after all, are generally the > user-facing part of the app), then in 99 cases out of 100, I''d say you > need to refactor the UI or split up the app.That is assuming these are end user facing controllers (as opposed to ones for api clients). (and if the OP does indeed have 4 apps then they have already split up the app) Fred> > Best, > -- > Marnen Laibow-Koserhttp://www.marnen.org > mar...-sbuyVjPbboAdnm+yROfE0A@public.gmane.org > -- > Posted viahttp://www.ruby-forum.com/.-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Marnen Laibow-Koser
2010-Jan-19 15:26 UTC
Re: Tutorial - Creating a Global REST Controller
Frederick Cheung wrote:> On Jan 19, 2:58 pm, Marnen Laibow-Koser <li...-fsXkhYbjdPsEEoCn2XhGlw@public.gmane.org> wrote: >> > I very rarely use plugins in my app. I don''t like to use code that I >> > can''t control myself. I would rather find a plugin that is suitable, >> > dive into the code, learn from it, and create my own modified plugins. >> >> http://c2.com/cgi/wiki?NotInventedHere >> >> I have the opposite philosophy. If someone has already written >> something suitable, I see little reason to duplicate their effort. >> Extend it, sure. Write something that''s a better fit for me, sure. > > I find it a difficult one to call - while the above is true it''s > horrible find come rails upgrade time that the author has abandoned > the project.That''s certainly true.> Lots of rails plugins are small one man things - I would > certainly hesitate to use a plugin unless either it has sufficient > backing/momentum that I can trust it will stay around or I understand > it enough that I could rewrite it if I had to.Also a good point. I mention make_resourceful because it doesn''t seem to be going away, and Hampton Catlin is certainly not going away (well, unless he pulls a _why).> >> See, the number of controllers is a UI issue. No matter how many types >> of object you''re dealing with under the hood, if the user has to >> navigate among 300 controllers (which, after all, are generally the >> user-facing part of the app), then in 99 cases out of 100, I''d say you >> need to refactor the UI or split up the app. > > That is assuming these are end user facing controllers (as opposed to > ones for api clients).True, although what API you expose is sort of a UI issue. In any case, an API so bloated that it exposes 300 controllers is scary. :)> (and if the OP does indeed have 4 apps then > they have already split up the app)Right. In which case it''s not one app and, at least to me, it doesn''t mean much to count the total number of controllers across the 4 apps. But on reflection, I see that the original point was code duplication, so from that point of view it *may* make sense. Hmm.> > FredBest, -- Marnen Laibow-Koser http://www.marnen.org marnen-sbuyVjPbboAdnm+yROfE0A@public.gmane.org -- Posted via http://www.ruby-forum.com/. --0022158df84f5d0e38047d861883 Content-Type: text/plain; charset=ISO-8859-1 -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en. --0022158df84f5d0e38047d861883--
Thanks again guys for your input. As a point of clarification... My app(s) contain a combined 63 controllers across 4 applications, so if you wanted to divide that number by 4 you have less than 16 controllers. Many of these controllers are "not" client-facing controllers. I have really 6 client-facing controllers in my entire combined app cluster. The point of this thread was how to reduce code duplication across multiple controllers. I threw out an absurd amount of controllers to make a point of reference. As for the topic on plugins, I''m in agreement with Fred on this. I have experienced on quite a few occassions upgrading to a newer version of rails only to find out the author abandoned the project and I had to dig into the code and fix it all myself. There are plugins that I do use that I do not create or modify myself that have substantial backing. RedCloth is an example of this. Restful_Authentication is another. -- Posted via http://www.ruby-forum.com/. -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Marnen Laibow-Koser
2010-Jan-19 17:49 UTC
Re: Tutorial - Creating a Global REST Controller
Alpha Blue wrote:> Thanks again guys for your input. As a point of clarification... > > My app(s) contain a combined 63 controllers across 4 applications, so if > you wanted to divide that number by 4 you have less than 16 controllers. > Many of these controllers are "not" client-facing controllers. I have > really 6 client-facing controllers in my entire combined app cluster.Ah, that makes more sense. :)> > The point of this thread was how to reduce code duplication across > multiple controllers. I threw out an absurd amount of controllers to > make a point of reference.OK. It seemed like you were talking about an actual case. Sorry for misunderstanding.> > As for the topic on plugins, I''m in agreement with Fred on this. I have > experienced on quite a few occassions upgrading to a newer version of > rails only to find out the author abandoned the project and I had to dig > into the code and fix it all myself.I''ve only experienced that very rarely. Then again, I try not to choose plugins that look stagnant in the first place.> > There are plugins that I do use that I do not create or modify myself > that have substantial backing. RedCloth is an example of this. > Restful_Authentication is another.(Of course, those happen to be two of the most broken plugins in common use...RedCloth, at least for a while, had sort of stagnated (is that still so?), and restful_authentication is based on generated crap code, and should be abandoned completely in favor of Authlogic.) Best, -- Marnen Laibow-Koser http://www.marnen.org marnen-sbuyVjPbboAdnm+yROfE0A@public.gmane.org -- Posted via http://www.ruby-forum.com/. -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
> (Of course, those happen to be two of the most broken plugins in common > use...RedCloth, at least for a while, had sort of stagnated (is that > still so?), and restful_authentication is based on generated crap code, > and should be abandoned completely in favor of Authlogic.) >RedCloth has gotten better and there are multiple versions of the gem with some being more updated than others. I try to find the people that use it the most and I use that gem or compile the binaries myself. I liked restful authentication when I first tried it out but I have to agree with you that it''s missing a lot of features that I personally would like to have in an authentication system. I''ve had to tailor it to fit my needs. I''ll take a peek at Authlogic and see what it has to offer. Not to get off topic, but what do you personally like about Authlogic, or some of the big features? Thanks mate. -- Posted via http://www.ruby-forum.com/. -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.