Handling multiple filters (params) cleanly in controller
ruby, ruby-on-rails, ruby-on-rails-3, ruby-on-rails-3.1
Solution
You'll be better off following the convention of "fat models, skinny controllers", meaning you should put this kind of logic in the model itself. The `Post` class should be able to report which posts correspond to your conditions, so you can define a method to do that:
class Post < ActiveRecord::Base
...
def self.by_category_and_type(category = nil, type = nil)
return where(category: category, type: type) if category && type
return where(category: category) if category
return where(type: type) if type
all
end
...
end
Then in your controller you can just call
`@posts = Post.by_category_and_type(params[:category], params[:type])`
I haven't tested this, but I think it should do the trick. Let me know if it doesn't!
Problem
I have a class called Post, and I need to be able to accommodate the following scenarios: - If a user selects a category, only show posts from that category - If a user selects a type, only show posts with that type - If a user selects a category and type, only show posts from that category with that type - If a user selects nothing, show all posts I'm wondering if it's inevitable that my controller is just going to look gross with a ton of conditionals... here's my flawed approach at tackling this – does anyone know how I can accomplish this? ``` class PostsController < ApplicationController def index @user = current_user # If a user has not specified a type or category, # show them everything @posts = Post.all # If a user has selected a category, but no type, only # show posts from that category. if params[:category] && !params[:type] category = Category.find(params[:category]) @posts = @category.posts end # If a user has selected a category and a type, only show # posts from that category with that type if params[:category] && params[:type] category = Category.find(params[:category]) type = params[:type] @posts = category.posts.where(post_type: type) end # If a user has selected a type but not a category, show all # of the posts with that type if params[:type] && !params[:category] type = params[:type] @posts = Post.where(post_type: post_type) end end end ```