这是我对此的看法,在某种程度上改编自Justin Weiss 的方法:
# app/models/concerns/filterable.rb
module Filterable
extend ActiveSupport::Concern
class_methods do
def filter(params)
return self.all unless params.key? :filter
params[:filter].inject(self) do |query, (attribute, value)|
query.where(attribute.to_sym => value) if value.present?
end
end
end
end
# app/models/user.rb
class User < ActiveRecord::Base
include Filterable
end
# app/controllers/users_controller.rb
class UsersController < ApplicationController
# GET /users
# GET /users?filter[attribute]=value
def index
@users = User.filter(filter_params)
end
private
# Define which attributes can this model be filtered by
def filter_params
params.permit(filter: :username)
end
end
然后,您将通过发出GET /users?filter[username]=joe
. 这也适用于没有过滤器(返回User.all
)或没有值的过滤器(它们被简单地跳过)。
那里是为了filter
遵守 JSON-API。通过关注模型,您可以保持代码干燥,并且只将其包含在您想要过滤的任何模型中。我还使用了强大的参数来对“可怕的互联网”实施某种保护。
当然,您可以自定义此关注点并使其支持数组作为过滤器的值。