Ruby on rails 在控制器中干净地处理多个过滤器(参数)
我有一个名为Post的类,我需要能够适应以下场景:Ruby on rails 在控制器中干净地处理多个过滤器(参数),ruby-on-rails,ruby,ruby-on-rails-3,ruby-on-rails-3.1,Ruby On Rails,Ruby,Ruby On Rails 3,Ruby On Rails 3.1,我有一个名为Post的类,我需要能够适应以下场景: 如果用户选择类别,则仅显示该类别中的帖子 如果用户选择一种类型,则仅显示该类型的帖子 如果用户选择类别和类型,则仅显示该类别中具有该类型的帖子 如果用户未选择任何内容,则显示所有帖子 我想知道我的控制器是否不可避免地会带有大量的条件句。。。这是我处理这个问题的有缺陷的方法——有人知道我如何做到这一点吗 class PostsController < ApplicationController def index @use
- 如果用户选择类别,则仅显示该类别中的帖子
- 如果用户选择一种类型,则仅显示该类型的帖子
- 如果用户选择类别和类型,则仅显示该类别中具有该类型的帖子
- 如果用户未选择任何内容,则显示所有帖子
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
class PostsController
遵循“胖模型,瘦控制器”的惯例会更好,这意味着您应该在模型本身中加入这种逻辑。Post
类应该能够报告哪些Post与您的条件相对应,因此您可以定义一种方法来实现这一点:
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
class Post
然后,在控制器中,您可以直接调用
@posts=Post.by_category_和_type(params[:category],params[:type])
我还没有测试过这个,但我认为它应该可以。如果没有,请告诉我 您可以像这样重构代码: 控制器:
def index
@user = current_user
@posts = find_posts
end
private
def category
Category.find(params[:category])
end
def find_posts
if type = params[:type]
if params[:category]
category.posts.of_type(type)
else
Post.of_type(type)
end
elsif params[:category]
category.posts
else
Post.all
end
end
将范围添加到您的Post
模型中,根据需要命名:
scope:of_type,->(type){where(post_type:type)}
我建议你使用
上面的代码不是最好的,但是你可以用这个gem来改进它。
您甚至可以创建一个新类,负责查找帖子,并在您的控件中使用该类。Cheezus!这绝对是我们应该使用的模式。