Ruby on rails 在RAILS API控制器索引操作中应用过滤器哈希是否有一种简单的方法?
根据JSON API规范,我们应该使用过滤器查询参数来过滤控制器中的记录。filter参数实际上是什么并没有被真正指定,但是因为它应该能够包含多个搜索条件,所以显而易见的做法是使用散列 问题是,对于不同类型的记录,我似乎经常在控制器操作中重复自己 下面是一个包含ID列表的过滤器(用于获取多个特定记录)的情况 对于嵌套属性检查,我想我可以使用Ruby on rails 在RAILS API控制器索引操作中应用过滤器哈希是否有一种简单的方法?,ruby-on-rails,dry,rails-api,json-api,Ruby On Rails,Dry,Rails Api,Json Api,根据JSON API规范,我们应该使用过滤器查询参数来过滤控制器中的记录。filter参数实际上是什么并没有被真正指定,但是因为它应该能够包含多个搜索条件,所以显而易见的做法是使用散列 问题是,对于不同类型的记录,我似乎经常在控制器操作中重复自己 下面是一个包含ID列表的过滤器(用于获取多个特定记录)的情况 对于嵌套属性检查,我想我可以使用fetch或andand,但它看起来仍然不够干爽,我仍然在不同的控制器上执行相同的操作 有什么方法可以让我看起来更好,而不是重复我自己吗?你可以用来干燥
fetch
或andand
,但它看起来仍然不够干爽,我仍然在不同的控制器上执行相同的操作
有什么方法可以让我看起来更好,而不是重复我自己吗?你可以用来干燥
##================add common in app/models/concerns/common.rb
module Common
extend ActiveSupport::Concern
# included do
##add common scopes /validations
# end
##NOTE:add any instance method outside this module
module ClassMethods
def Find_using_filters (params)
Rails.logger.info "calling class method in concern=======#{params}=="
##Do whatever you want with params now
#you can even use switch case in case there are multiple models
end
end
end
##======================include the concern in model
include Common
##=======================in your controller,call it directly
Image.Find_using_filters params
对于服务对象来说,这似乎是一个很好的用法,而不是使用关注点在多个地方包含相同的代码
class CollectionFilter
def initialize(filters={})
@filters = filters
end
def results
model_class.find(ids)
end
def ids
return [] unless @filters[:id]
@filters[:id].split(",").map(&:to_i)
end
def model_class
raise NotImplementedError
end
end
您可以如上所述编写一个通用的CollectionFilter
,然后使用子类为特定用例添加功能
class VideoFilter < CollectionFilter
def results
super.where(name: name)
end
def name
@filters[:name]
end
def model_class
Video
end
end
以下是我对这一点的看法,有些改编自:
#app/models/concerns/filterable.rb
可过滤模块
扩展ActiveSupport::关注点
类方法做什么
def过滤器(参数)
返回self.all,除非params.key?:滤波器
params[:filter].inject(self)do | query,(属性,值)|
如果value.present,则查询.where(attribute.to_sym=>value)?
结束
结束
结束
结束
#app/models/user.rb
类用户
然后通过发出一个GET/users?filter[username]=joe
来过滤结果。这适用于没有筛选器(返回User.all
)或没有值的筛选器(它们只是被跳过)
过滤器
符合JSON-API。通过关注模型,您可以保持代码干燥,并且只将其包含在您想要过滤的任何模型中。我还使用了强大的参数来实施某种针对“可怕的互联网”的保护
当然,您可以自定义此关注点,并使其支持数组作为筛选器的值。比关注点方法要好得多
class VideoFilter < CollectionFilter
def results
super.where(name: name)
end
def name
@filters[:name]
end
def model_class
Video
end
end
def index
videos = VideoFilter.new(params[:filter]).results
render json: videos
end
# 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