"Assignment Branch Condition size for call is too high" 在 rails 查询对象中



我在一个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

为简洁起见,筛选方法是删除的私有方法。

调用方法给出"分配分支条件太高"的 rubocop 警告,这是有道理的,因为它做了很多。如何重构它以绕过 rubocop 警告?

我看到了一些类似的问题,但没有一个能解决我的问题。

有很多方法可以在 Rails 中构建作用域而不使用重新分配,而重新分配只是懒惰的方法。

您可以在模型本身上创建可链接的范围:

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

这将允许您调用:

Doctor.filter_by_speciality(params[:speciality])
.filter_by_name(params[:name])
# etc

始终返回 self 或其他范围将防止 nil 错误。

还可以使用.merge来组合作用域。

Doctor.where(name: 'John').merge(
Doctor.where(specialty: 'pediatrician')
)

因此,如果您首先重构这些方法中的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

最新更新