我有以下索引方法
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") %>
我看不出怎么写。我应该使用示波器还是应该在控制器中使用替代方法?我最初的“在哪里”过滤首先是一种不好的做法吗?
答案 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