# Different views for the same function

**URL:** <https://www.ruby-forum.com/t/different-views-for-the-same-function/111556>\
**Category:** Rails\
**Created:** [August 8, 2007, 3:56pm UTC](https://www.ruby-forum.com/t/different-views-for-the-same-function/111556 "2007-08-08T15:56:12Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![taro](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/df705f/32.png) [@taro](https://www.ruby-forum.com/u/taro)\
**Post date:** [August 8, 2007, 3:56pm UTC](https://www.ruby-forum.com/t/different-views-for-the-same-function/111556/1 "2007-08-08T15:56:12Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![taro](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/df705f/32.png) [@taro](https://www.ruby-forum.com/u/taro)\
**Post date:** [August 8, 2007, 4:37pm UTC](https://www.ruby-forum.com/t/different-views-for-the-same-function/111556/2 "2007-08-08T16:37:28Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![taro](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/df705f/32.png) [@taro](https://www.ruby-forum.com/u/taro)\
**Post date:** [August 8, 2007, 4:41pm UTC](https://www.ruby-forum.com/t/different-views-for-the-same-function/111556/3 "2007-08-08T16:41:34Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![taro](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/df705f/32.png) [@taro](https://www.ruby-forum.com/u/taro)\
**Post date:** [August 8, 2007, 5:25pm UTC](https://www.ruby-forum.com/t/different-views-for-the-same-function/111556/4 "2007-08-08T17:25:53Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![taro](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/df705f/32.png) [@taro](https://www.ruby-forum.com/u/taro)\
**Post date:** [August 9, 2007, 4:45am UTC](https://www.ruby-forum.com/t/different-views-for-the-same-function/111556/5 "2007-08-09T04:45:54Z")

</div>

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.

> ## 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
