Polymorphic Controllers and Views

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

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

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

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

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

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