Как отобразить идентификаторы в запросе - PullRequest
0 голосов
/ 06 марта 2019

У меня есть модели Грузовик и Экипаж, Грузовик has_many :crews. На внешней стороне флажков я выбираю идентификаторы грузовиков и отправляю их на мой контроллер. Мне нужно уничтожать только грузовики без экипажей. Что у меня сейчас:

# app/models/truck.rb
belongs_to :company
has_many :crews

# app/models/crew.rb
belongs_to :truck, optional: true

# trucks_controller.rb
def bulk_destroy
  trucks_with_crews = []
  current_company.trucks.where(id: params[:ids]).find_each do |truck|
    if truck.crews.exists?
      trucks_with_crews << truck
      next
    end
    truck.destroy
  end
  if trucks_with_crews.empty?
    head :no_content
  else
    message = []
    trucks_with_crews.each_with_object([]) { |x| message << x.name }
    render json: { message: "Trucks: '#{message.join(', ')}' can't be deleted because used by crews." }, status: :unprocessable_entity
  end
end

Но это очень сложно, и я хочу улучшить его в запросе. Кто-нибудь может мне помочь?

Я думаю, это должно быть что-то вроде:

  • выберите идентификаторы всех, кто не может быть удален (конечно, из тех, чьи Идентификаторы пришли к нам)
  • вычесть их из общего списка входящих идентификаторов
  • удалить оставшиеся в общем списке

Я не знаю точно, как это сделать:

a = current_company.trucks.where(id: params[:ids])
b = current_company.trucks.includes(:crews).where(truck.crews.map(&:id))
a = a - b

Надеюсь, вы понимаете, о чем я. Спасибо:)

1 Ответ

1 голос
/ 06 марта 2019

Сначала вы можете добавить ограничение к модели грузовика, чтобы случайно не удалить грузовик с экипажем

has_many :crews, dependent: :restrict_with_exception 

Давайте проведем рефакторинг кода вашего контроллера:

def bulk_destroy      
  # let find truck which should be deleted
  trucks_wo_crew = current_company.trucks.includes(:crews)
    .where(id: params[:ids]).where(crews: { id: nil })
  # and delete them
  trucks_wo_crew.destroy_all

  # if we search by id after deletion we'll get trucks with crew, 
  # because we already deleted other. 
  # We can get only names, since we don't need other info
  trucks_with_crew = current_company.trucks.where(id: params[:ids]).pluck(:name)

  return head :no_content if trucks_with_crew.empty?

  render json: { message: "Trucks: '#{trucks_with_crew.join(', ')}' can't be deleted because used by crews." }, status: :unprocessable_entity
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...