过滤索引

时间:2014-06-25 21:31:24

标签: ruby-on-rails ruby-on-rails-4

我有以下索引方法

def index
    @user = User.find_by_username(params[:user_id])
    @search = @user.collections.where(status: params[:status]).search(params[:q])
    @search.sorts = 'created_at desc' if @search.sorts.empty?  
    @collections = @search.result.paginate(page: params[:page])
end

然后,我可以使用以下链接显示具有该一个操作的不同索引

<%= link_to "Collection", user_collections_path(current_user, :status => "Got") %>

<%= link_to "Wantlist", user_collections_path(current_user, :status => "Want") %>

但我希望能够链接这样的事情,使用其他字段来过滤索引

<%= link_to "Assembled", user_collections_path(current_user, :progress => "Assembled") %>

我看不出怎么写。我应该使用示波器还是应该在控制器中使用替代方法?我最初的“在哪里”过滤首先是一种不好的做法吗?

3 个答案:

答案 0 :(得分:1)

我发现这样做的最好方法是使用has_scope gem。

已安装。在我的模型中命名范围如下

scope :assembled, -> { where(progress: 'Assembled') }
scope :got, -> { where(status: 'Got') }
scope :want, -> { where(status: 'Want') }

将has_scope字段添加到控制器

has_scope :got, :type => :boolean
has_scope :want, :type => :boolean
has_scope :assembled, :type => :boolean

然后我的索引方法如下

def index
    @user = User.find_by_username(params[:user_id])
    @search = apply_scopes(@user.collections).search(params[:q])
    @search.sorts = 'created_at desc' if @search.sorts.empty?  
    @collections = @search.result.paginate(page: params[:page])
end

然后我可以使用这个范围的任意组合链接到索引

<%= link_to collection, user_collections_path(@user, got: true) %>

<%= link_to assembled, user_collections_path(@user, got: true, assembled: true) %>

没有路线,没有额外的方法。非常干净和可扩展。

答案 1 :(得分:0)

使用Gem

这是一个已解决的问题。我会使用像ransack这样的宝石来做这件事,而不是重新发明轮子。它有很好的帮助方法来提供您需要的任何类型的过滤。

答案 2 :(得分:0)

<强>路线

San的答案之后,您需要创建routes来处理您希望发送到index的任何数据(用于过滤):

你会做这样的事情:

#config/routes.rb
resources :users, except: :show do
   collection do
      get "(:query)", action: :index #-> domain.com/users/:query
   end
end

这将允许您创建如下链接:

<%= link_to "Link", users_path(current_user, query: "whatever") %>

-

<强>控制器

在您的控制器中,所有链接都会点击您的index操作,因此您只需要一些条件来确保您可以处理“非搜索”请求:

def index
    @user = User.find_by_username(params[:user_id])

    if params[:status].present? && params[:q].present?
        @search = @user.collections.where(status: params[:status]).search(params[:q])
        @search.sorts = 'created_at desc' if @search.sorts.empty?  
        @collections = @search.result.paginate(page: params[:page])
    end
end