[英]"Assignment Branch Condition size for call is too high" in rails query object
I have a query object in a rails project which searches a resource with multiple filters (fees, name, specialty, years of experience).我在 rails 项目中有一个查询对象,它使用多个过滤器(费用、名称、专业、多年的经验)搜索资源。
class SearchDoctors
attr_accessor :initial_scope, :search_params
def self.call(initial_scope, search_params)
new(initial_scope, search_params).call
end
def initialize(initial_scope, search_params)
@initial_scope = initial_scope
@search_params = search_params
end
# Assignment branch condition on call method
def call
scoped = filter_by_speciality(initial_scope, search_params[:speciality])
scoped = filter_by_name(scoped, search_params[:name])
scoped = filter_by_fees(scoped,
search_params[:fees_from],
search_params[:fees_to])
filter_by_years_of_experience(scoped,
search_params[:experience_from],
search_params[:experience_to])
end
end
The filter methods are private methods removed for brevity.过滤器方法是为简洁起见删除的私有方法。
The call method gives "assignment branch condition is too high" rubocop warning, which makes sense because it does much. call 方法给出了“赋值分支条件太高”的 rubocop 警告,这是有道理的,因为它做了很多。 How I can refactor it to bypass the rubocop warning?我如何重构它以绕过 rubocop 警告?
I saw a few similar questions but none of them solved my problem.我看到了一些类似的问题,但没有一个能解决我的问题。
There are plenty of ways to construct scopes in Rails without using reassignment which just the lazy way to do it.在 Rails 中有很多方法可以在不使用重新分配的情况下构造作用域,这只是一种懒惰的方法。
You could make chainable scopes on the the model itself:您可以在模型本身上制作可链接的范围:
class Doctor < ApplicationRecord
def self.filter_by_speciality(speciality)
speciality.present ? self.where(speciality: speciality) : self
end
def self.filter_by_name(name)
name.present ? self.where(name: name) : self
end
end
That will let you call:这会让你打电话:
Doctor.filter_by_speciality(params[:speciality])
.filter_by_name(params[:name])
# etc
Always returning self or another scope will prevent nil errors.始终返回 self 或其他范围将防止 nil 错误。
You can also use .merge
to combine scopes.您还可以使用.merge
来组合范围。
Doctor.where(name: 'John').merge(
Doctor.where(specialty: 'pediatrician')
)
So if you start by refactoring the scoped
argument out of those methods you can compose an array of scopes and merge them together:因此,如果您从这些方法中重构scoped
参数开始,您可以组合一个作用域数组并将它们合并在一起:
def call
# not going to list them all.
scopes = [filter_by_speciality(search_params[:speciality]), filter_by_name(search_params[:name])]
scopes.compact.each_with_object(initial_scope) do |filter, memo|
memo.merge(filter)
end
end
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.