«Размер условия ветви назначения для вызова слишком велик» в объекте запроса rails - PullRequest
0 голосов
/ 08 февраля 2020

У меня есть объект запроса в проекте 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

Методы фильтра - это частные методы, которые для краткости удалены.

Метод call выдает предупреждение rubocop "условие ветвления присваивания слишком высокое", что имеет смысл, потому что делает много. Как я могу изменить его, чтобы обойти предупреждение о рубокопе?

Я видел несколько похожих вопросов, но ни один из них не решил мою проблему.

1 Ответ

1 голос
/ 08 февраля 2020

Существует множество способов построения областей в 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

Всегда возвращая себя или другую область, вы избежите ошибок 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
...