Rails 5 - область с последней ассоциацией has_many - PullRequest
0 голосов
/ 24 сентября 2018

Я создаю отфильтрованную таблицу для моей пользовательской модели.Я создал несколько областей для их фильтрации.Я:

class User < ApplicationRecord
  has_many :invoices

  scope :application_approved, -> { ... }
  scope :application_denied, -> { ... }
  scope :latest_invoice_paid, -> { ... }
  scope :latest_invoice_not_paid, -> { ... }

  def self.__self__
    self
  end
end

и в контроллере:

def index
  filters = params[:statuses] || {}
  application_status = filters[:application_status].presence
  payments_status = filters[:payments_status].presence
  @vehicles = Vehicle.send(application_status || :__self__)
                     .send(payment_status || :__self__)
                     .paginate(:page => params[:page], :per_page => 10)
                     .order('created_at DESC')
end

Все фильтры работают изолированно, однако, когда они объединены в цепочку, фильтры, которые не применяются, похоже, отменяют ранеефильтры.

Например, если я установил фильтр, чтобы показывать только пользователей, которые заплатили, он работает.Но если я установлю фильтр, чтобы показывать только пользователей, которые были одобрены / не одобрены, все пользователи будут возвращаться все время.Кажется, что возвращение self, когда фильтр не применен, просто возвращает всех пользователей.

Итак, как я могу пропустить область, если для нее не применен фильтр?

1 Ответ

0 голосов
/ 24 сентября 2018

Что-то вроде этого должно сработать, это также помогает защитить ваш метод send .Поскольку могут выполняться только методы из белого списка.Приведенный ниже код выполняет следующие действия:

  1. Сначала создайте белый список с разрешенными ключами и допустимыми значениями.
  2. Получите params[:statuses] или, если он не существует, создайте новый Параметры объект.
  3. Разрешить только разрешенные ключи.
  4. Удалить все экземпляры значений ключей, которые не имеют значений из белого списка.
  5. Преобразовать разрешенные параметрыв хеш.
  6. Уменьшите полученную коллекцию.Начните с Vehicle.all и отправьте методы из белого списка (объедините их в цепочку).Если ключ или значение отсутствуют, они не будут зациклены, поэтому нет необходимости вызывать :__self__ или :itself.
  7. . Делать всю остальную логику.

def index
  whitelist = ActiveSupport::HashWithIndifferentAccess.new(
    application_status: %w[application_approved application_denied],
    payments_status: %w[latest_invoice_paid latest_invoice_not_paid],
  )

  filters = params[:statuses] || ActionController::Parameters.new

  @vehicles = 
    filters
    .permit(*whitelist.keys)
    .select { |key, value| whitelist[key].include?(value) }
    .to_h
    .reduce(Vehicle.all) { |vehicles, (_key, value)| vehicles.send(value) }
    .order(created_at: :desc)
    .paginate(page: params[:page], per_page: 10)
end

Ссылки:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...