This question is more for future reference after I''ve made my website, but one thing I''ve noticed was there was I had to make a lot of functions on the controller, and different views for each one, each with the same functionality. This is very anti-DRY, in my opinion. So I was wondering, Is there some way to wrap all this up into a single line of code in the controller, and ditto for the views? I know a bit about partials, but is rather unsure about how to deal with it in a form. How do I display a form partial, giving it different variables each time? For the controller, I have a few controllers extending off of user (thought the names are different, basically they''re the moderators and administrators). Since a user can edit itself, a mod can edit a user, and an admin edit a mod, I have a lot of duplication in methods, just so I can get different views off of each function. Since I''d rather wrap it up in one view for the higher classes, is there some way to wrap this unneeded extra functions using a bit of super() and different validation methods? Must I put edit_self() method in the Application controller? --~--~---------~--~----~------------~-------~--~----~ 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-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Taro, if you;re talking about the very common functions for basic CRUD operations on tables then yes, I think there are a few strategies to keep DRY. I can see by reading around that the RESTful approach has some pretty clear guidelines to help with this but I''m not there yet. What I have found extremely helpful is a strategy of defining a parent class from which I inherit for my classes (controllers) that do concrete work. So, lets call this controller Crud class Crud < ActionController::base bunch of stuff we''ll discuss below end and then my real controllers are class Concrete < Crud end Now in the Crud controller I define some methods, specifically in my case "show", "new", "edit" and "delete" (you can collapse these even further if you wanted but for me this has been a reasonable balance between being succint and being clear. The next part is to take advantage of Rails consistency in naming. So for a given controller we can deduce the model name. We know it will have an id field as primary key and if we manage our routes consistently then we know our parameters will be consistent. Then if we agree to use a standard instance variable name for our form data we can abstract the entire CRUD process. In my example, @row is what we agree to always be the variable that holds data from the database. Here''s an example for the "show" method: def show if !@row = crud_obj.find((params[:name]) then redirect_to home_url return end article_render_show end crud_obj is the model object related to our controller. It is defined as below. def crud_obj return Object.const_get(class_name) end def class_name return self.class.name.sub(/Controller/,"") end Once you have a way to abstract the name of the model class from the controller class, you can pretty much abstract the entire crud process. I now have several controllers than have absolutely no code in them whatsoever - they just inherit the methods from this parent class. To create a new class I simply: 1. Create a new class derived from Crud 2. Create the views "show" and "edit" 3. The logic will use "edit" for new and update functions, and "show" for the rest. You could easily decide to use only one view but I find they''re often different enough to warrant clear separation. If you then create a customer form builder you can get a lot of basic functionality built reliably very fast. Cheers, --Kip On Aug 8, 9:55 pm, Taro <japtar10...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> This question is more for future reference after I''ve made my website, > but one thing I''ve noticed was there was I had to make a lot of > functions on the controller, and different views for each one, each > with the same functionality. This is very anti-DRY, in my opinion. > > So I was wondering, Is there some way to wrap all this up into a > single line of code in the controller, and ditto for the views? > > I know a bit about partials, but is rather unsure about how to deal > with it in a form. How do I display a form partial, giving it > different variables each time? > > For the controller, I have a few controllers extending off of user > (thought the names are different, basically they''re the moderators and > administrators). Since a user can edit itself, a mod can edit a user, > and an admin edit a mod, I have a lot of duplication in methods, just > so I can get different views off of each function. Since I''d rather > wrap it up in one view for the higher classes, is there some way to > wrap this unneeded extra functions using a bit of super() and > different validation methods? Must I put edit_self() method in the > Application controller?--~--~---------~--~----~------------~-------~--~----~ 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-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Hi Taro, Taro wrote:> one thing I''ve noticed was there was I had to make a lot of > functions on the controller, and different views for each one, > each with the same functionality. This is very anti-DRY, in > my opinion. > > So I was wondering, Is there some way to wrap all this up > into a single line of code in the controller,Not sure if this is what you''re asking, but you can render whatever view you want from any controller action with :render => ''action''. That will render the view for the action specified using whatever instance variables you''ve created in the action you''re in.> and ditto for the views? > > I know a bit about partials, but is rather unsure about > how to deal with it in a form. How do I display a form > partial, giving it different variables each time?:locals => {:var_in_form, @var_from_controller, etc...} HTH, Bill --~--~---------~--~----~------------~-------~--~----~ 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-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
To Bill, Sorry, I was in a rush. I''ll try to explain this a little more thoroughly: Basically, I have user classes set-up as ApplicationController > UserController > ModeratorController > Admin Controller. As you can see, Mods inherits user methods, and Admins inherit Mods methods. The same goes for the Models; User > Moderator > Admin. Right now, my edit methods goes as follows: --------------------- class UserController < ApplicationController def edit_self @user=User.find(params[:user_id]) #check if you''re editting yourself. if params[:user_id]==@user.id #edit user end end end ----------------------- class ModeratorController < UserController #edit_self is inherited here. def edit_user @user=User.find(params[:user_id]) #check if you''re editting a user if @user.class.name==''User'' #edit user end end end ----------------------- class AdminController < ModeratorController #edit_self and edit_User is inherited here. def edit_moderator @user=User.find(params[:user_id]) #check if you''re editting a user if @user.class.name==''Moderator'' #edit moderator end end end ------------------------- Not only am I duplicating the same code as the class before (with an exception of different validations), but I have to create a separate view for each method! I just want to wrap up those methods in one single, inherited method edit_user. Any ideas? --~--~---------~--~----~------------~-------~--~----~ 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-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Hi Taro, Taro wrote:> Sorry, I was in a rush. I''ll try to explain this a little more > thoroughly:No problem.> Basically, I have user classes set-up as ApplicationController > > UserController > ModeratorController > Admin Controller.Why the chain? I mean, based on what I see below, Moderator and Admin could both inherit from User. Just asking in case there''s there some reason you haven''t covered here.> Right now, my edit methods goes as follows: > --------------------- > class UserController < ApplicationController > def edit_self > @user=User.find(params[:user_id]) > #check if you''re editting yourself. > if params[:user_id]==@user.id > #edit user > end > end > end > ----------------------- > class ModeratorController < UserController > #edit_self is inherited here. > def edit_user > @user=User.find(params[:user_id]) > #check if you''re editting a user > if @user.class.name==''User'' > #edit user > end > end > end > ----------------------- > class AdminController < ModeratorController > #edit_self and edit_User is inherited here. > def edit_moderator > @user=User.find(params[:user_id]) > #check if you''re editting a user > if @user.class.name==''Moderator'' > #edit moderator > end > end > end > -------------------------> Not only am I duplicating the same code as the class before (with an > exception of different validations),Different validations may be a good enough reason, in fact a very good reason, NOT to try to refactor these into a single, parameter driven, controller method. I guess the key question I''d have is this. You''ve shown that you have two redundant lines of code in each method. The ''#check if you''re editing a ?'' line is probably just that''; a line. But what''s the level of similarity between the code blocks behind the ''#edit something'' comments? It would be a pretty straight-forward exercize to put this in application.rb. The question I''d recommend you focus on is ''what would that do to the readability and maintainability of my code''? Refactoring just to reduce lines of code is not, IMO, a good expenditure of effort. Refactor this if you think that you''re going to have to make the same change in 3 places every time you make any change. OTOH, if you think you may end up making changes to one but not the others, then let it be ''til you learn more.> but I have to create a separate view for each method!No you don''t. As I said earlier, you can pass your instance variables to any view you want to use to render them. That attempt will also shed light on whether or not your desire to use a single method to process all your user types is really a viable idea. HTH, Bill --~--~---------~--~----~------------~-------~--~----~ 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-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---