# Polymorphic Controllers and Views

**URL:** <https://www.ruby-forum.com/t/polymorphic-controllers-and-views/149173>\
**Category:** Rails\
**Created:** [September 22, 2008, 8:48am UTC](https://www.ruby-forum.com/t/polymorphic-controllers-and-views/149173 "2008-09-22T08:48:34Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![elioncho](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/ed8c4c/32.png) [@elioncho](https://www.ruby-forum.com/u/elioncho)\
**Post date:** [September 22, 2008, 8:48am UTC](https://www.ruby-forum.com/t/polymorphic-controllers-and-views/149173/1 "2008-09-22T08:48:34Z")

</div>

How can I maintain DRY code on polymorphic controllers and views? For  
example, I am building an app where users have many posts and at the  
same time a group can have many posts and a category can be related to  
many posts (post belongs to a user, category and a group).

groups/1/posts  
users/1/posts  
category/1/posts

So what happens then to the posts\_controller? How can I know for  
example if I want to show the posts for a group, the posts of a  
specific user or category?

Someone could tell me to do something like this:

def index  
if params[:group\_id]  
@posts = Post.find(:all, :conditions =\> ["group\_id = ?,  
params[:group\_id])  
elsif params[:user\_id]  
@posts = Post.find(:all, :conditions =\> ["user\_id = ?,  
params[:user\_id])  
elsif params[:category\_id]  
@posts = Post.find(:all, :conditions =\> ["category\_id = ?,  
params[:category\_id])  
end  
end

But then again this code will be unsustainable in the future when more  
routes are added (ifs block will be hell). And when I take into  
account that the views and links should render differently for each  
case makes it worst.

What’s the best solution for this? Any suggestions or guidelines are  
appreciated.

Thanks,

Elioncho

---

<div class="post-metadata">

**Author:** ![elioncho](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/ed8c4c/32.png) [@elioncho](https://www.ruby-forum.com/u/elioncho)\
**Post date:** [September 22, 2008, 4:52pm UTC](https://www.ruby-forum.com/t/polymorphic-controllers-and-views/149173/2 "2008-09-22T16:52:45Z")

</div>

Anyone? I am truly lost on which approach to take

---

<div class="post-metadata">

**Author:** ![elioncho](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/ed8c4c/32.png) [@elioncho](https://www.ruby-forum.com/u/elioncho)\
**Post date:** [September 22, 2008, 5:26pm UTC](https://www.ruby-forum.com/t/polymorphic-controllers-and-views/149173/3 "2008-09-22T17:26:28Z")

</div>

On Sep 22, 10:52 pm, elioncho [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Anyone? I am truly lost on which approach to take

Try this one:

def index  
args = {}  
[:user\_id, :group\_id, :category\_id].each do |k|  
args[k] = params[k]  
end

@posts = Post.find(:all, :conditions =\> args)  
end

This way you also get:

/users/1/categories/1/posts  
/groups/1/categories/1/posts  
…

---

<div class="post-metadata">

**Author:** ![elioncho](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/ed8c4c/32.png) [@elioncho](https://www.ruby-forum.com/u/elioncho)\
**Post date:** [September 23, 2008, 8:36am UTC](https://www.ruby-forum.com/t/polymorphic-controllers-and-views/149173/4 "2008-09-23T08:36:46Z")

</div>

Well, I think I didn´t write my question correctly, I’ll try to be  
more explicit.

In the app I am working on, users can create posts like in a blog. The  
app emphasizes on the fact of belonging to a group. So a post belongs  
to a group and a user (table posts has a user\_id and group\_id column).  
I want to show the list of posts that belong to certain group. I use  
the index action from the posts\_controller to show all the posts that  
belong to a certain group through the route groups/1/posts. Also, I  
show other things such as: most recommended posts and more active  
users, all in the same index action and view.

It’s here where the problem starts. I want to also show the index of  
the posts made by a specific user (the route should be users/1/posts)  
and additional info too. I thought about using chains of ifs and elses  
(asking for params in the route to know which data to show) in the  
index action and views as an “easy, dirty and unmaintainable  
solution”. But there are more problems. There should be a option to  
filter the posts of a group by category and tags (and this too applies  
to posts for a specific user). This is where the problems becomes a  
snow ball. The fact that there should always be filtering for a  
specific group or user. And that’s without taking into account the  
views which will show different information depending on the context  
(user or group). I thought about having various controllers but it  
seems illogical: post\_users, post\_groups, post\_user\_categories,  
post\_group\_categories, post\_user\_tags, post\_group\_tags…

So that’s it. I don’t know which is the right move. Any help or  
suggestion is appreciated.

Thanks,

Elías

---

<div class="post-metadata">

**Author:** ![elioncho](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/ed8c4c/32.png) [@elioncho](https://www.ruby-forum.com/u/elioncho)\
**Post date:** [September 22, 2008, 11:38pm UTC](https://www.ruby-forum.com/t/polymorphic-controllers-and-views/149173/5 "2008-09-22T23:38:43Z")

</div>

Elias O. wrote:

> Anyone? I am truly lost on which approach to take

This post may be able to help you;

> **[DRYing Up Polymorphic Controllers](http://revolutiononrails.blogspot.com/2007/05/drying-up-polymorphic-controllers.html)**
>
> Polymorphic routes allow drying up the controller implementation when functionality is identical, regardless of entry point. A good example ...

---

<div class="post-metadata">

**Author:** ![elioncho](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/ed8c4c/32.png) [@elioncho](https://www.ruby-forum.com/u/elioncho)\
**Post date:** [September 23, 2008, 8:36am UTC](https://www.ruby-forum.com/t/polymorphic-controllers-and-views/149173/6 "2008-09-23T08:36:47Z")

</div>

Well, I think I didn´t write my question correctly, I’ll try to be  
more explicit.

In the app I am working on, users can create posts like in a blog. The  
app emphasizes on the fact of belonging to a group. So a post belongs  
to a group and a user (table posts has a user\_id and group\_id column).  
I want to show the list of posts that belong to certain group. I use  
the index action from the posts\_controller to show all the posts that  
belong to a certain group through the route groups/1/posts. Also, I  
show other things such as: most recommended posts and more active  
users, all in the same index action and view.

It’s here where the problem starts. I want to also show the index of  
the posts made by a specific user (the route should be users/1/posts)  
and additional info too. I thought about using chains of ifs and elses  
(asking for params in the route to know which data to show) in the  
index action and views as an “easy, dirty and unmaintainable  
solution”. But there are more problems. There should be a option to  
filter the posts of a group by category and tags (and this too applies  
to posts for a specific user). This is where the problems becomes a  
snow ball. The fact that there should always be filtering for a  
specific group or user. And that’s without taking into account the  
views which will show different information depending on the context  
(user or group). I thought about having various controllers but it  
seems illogical: post\_users, post\_groups, post\_user\_categories,  
post\_group\_categories, post\_user\_tags, post\_group\_tags…

So that’s it. I don’t know which is the right move. Any help or  
suggestion is appreciated.

Thanks,

Elías

---

<div class="post-metadata">

**Author:** ![elioncho](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/ed8c4c/32.png) [@elioncho](https://www.ruby-forum.com/u/elioncho)\
**Post date:** [September 23, 2008, 9:28am UTC](https://www.ruby-forum.com/t/polymorphic-controllers-and-views/149173/7 "2008-09-23T09:28:57Z")

</div>

On Sep 23, 2:35 pm, elioncho [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> users, all in the same index action and view.  
> specific group or user. And that’s without taking into account the  
> Elías  
> Reposting, since I think this may be close to what you’re looking for:

def index  
args = {}  
[:user\_id, :group\_id, :category\_id, :tag\_id].each do |k|  
args[k] = params[k] if params[k]  
end

@posts = Post.find(:all, :conditions =\> args)  
end

Which will filter for the following, assuming you’ve setup your routes  
correctly:

/users/1/posts  
/groups/1/posts  
/categories/1/posts  
/tags/1/posts  
/users/1/categories/1/posts  
/users/1/tags/1/posts  
/groups/1/categories/1/posts  
/groups/1/tags/1/posts  
…  
/groups/1/users/1/categories/1/tags/1/posts (although I doubt you’ll  
be having this kind of route)

In short, it will accept filters for a route with a combination of  
users, groups, categories, and tags.

HTH

---

<div class="post-metadata">

**Author:** ![elioncho](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/ed8c4c/32.png) [@elioncho](https://www.ruby-forum.com/u/elioncho)\
**Post date:** [September 23, 2008, 10:28am UTC](https://www.ruby-forum.com/t/polymorphic-controllers-and-views/149173/8 "2008-09-23T10:28:13Z")

</div>

Thanks for your support Erol.

I guess I’ll have to put some extra ifs and elses because I have to  
show additional data on the index action and view. (not only @posts,  
for example for group index posts I must show a list of latest posts  
from the group, but also the most commented and active posts + a tag  
cloud.

Your proposed solution is good, but I am worried about the views. Any  
ideas on how to maintain the views clean and dry? I am imaging myself  
writing tons of ifs and elses on the index view.

Thanks again,

Elías
