Как построить запрос в контроллере, но сделать только один вызов БД - PullRequest
0 голосов
/ 21 декабря 2018

Моя идея для метода #index контроллера состоит в том, чтобы установить things = Thing.all, а затем, если есть параметры фильтра, проверить их один за другим и включить их в цепочку, чтобы в конце вы остались с однимзапрос для выполнения.Но следующие запросы выполняются так, как они называются:

def things_controller
  def index
    things = Thing.all #<-- db call #1

    if params[:color]
      things = things.where(color: params[:color]) #<-- db call #2
    end

    render json: things  #<-- I would like to make a single db call here instead
  end
end

Как я могу предотвратить несколько ненужных вызовов БД?Есть ли какое-то соглашение для параметров фильтра, которые я должен использовать?

Ответы [ 2 ]

0 голосов
/ 21 декабря 2018

Вам просто нужно реорганизовать код следующим образом:

  def index
    things = if params[:color]
               Thing.where(color: params[:color])
             # ...else if 
             else
               Thing.all
             end
    render json: things
  end

Обновлено

Если вы хотите объединить предложения where, сделайте следующее:

def index
  valid_params_keys = %w(color size)

  filtered_keys = valid_params_keys.select { |key| params.keys.include?(key) }

  # Don't need conditional check anymore :).
  @products = filtered_keys.inject(Product.all) do |scope, key|
    scope.where(key => params[key])
  end 
end
0 голосов
/ 21 декабря 2018

Поскольку things является массивом, вы можете сделать это, что является только операцией с массивом.

def index
  things = Thing.all

  if params[:color]
    things = things.select!{ |thing| thing.color == params[:color]}
  end

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