500 Внутренняя ошибка сервера и просмотр неправильной таблицы при попытке сделать запрос на удаление в rails

#ruby-on-rails #ruby #crud

Вопрос:

Я пытался заставить некоторые базовые функции CRUD работать в моем приложении rails, но УДАЛЕНИЕ, в частности, продолжает показывать внутреннюю ошибку сервера 500.

 Started DELETE "/developers/7" for ::1 at 2021-09-27 13:40:00  0530
Processing by DevelopersController#destroy as */*
  Parameters: {"id"=>"7"}
   (0.2ms)  SELECT sqlite_version(*)
  ↳ app/controllers/developers_controller.rb:44:in `set_developer'
  Developer Load (0.4ms)  SELECT "developers".* FROM "developers" WHERE "developers"."id" = ? LIMIT ?  [["id", 7], ["LIMIT", 1]]
  ↳ app/controllers/developers_controller.rb:44:in `set_developer'
  TRANSACTION (0.1ms)  begin transaction
  ↳ app/controllers/developers_controller.rb:38:in `destroy'
  TRANSACTION (0.1ms)  rollback transaction
  ↳ app/controllers/developers_controller.rb:38:in `destroy'
Completed 500 Internal Server Error in 9ms (ActiveRecord: 1.6ms | Allocations: 2233)


  
ActiveRecord::StatementInvalid (Could not find table 'developers_teams'):
  
app/controllers/developers_controller.rb:38:in `destroy'
 

Фактическая модель, которую я хочу, чтобы она изучила developer , и запросы get и post делают это просто отлично, но она продолжает говорить, что не может найти таблицу developers_teams , которая является моей таблицей объединения для связи HABTM между developer и team .

Соответствующие модели:

 
team.rb

class Team < ApplicationRecord
    validates :name, presence: true
    has_many :messages
    has_and_belongs_to_many :developers
end

developer.rb

class Developer < ApplicationRecord
    validates :full_name, presence: true
    has_and_belongs_to_many :teams
end
 

Контроллер для разработчиков:

 class DevelopersController < ApplicationController
  before_action :set_developer, only: [:show, :update, :destroy]

  # GET /developers
  def index
    @developers = Developer.all

    render json: @developers
  end

  # GET /developers/1
  def show
    render json: @developer
  end

  # POST /developers
  def create
    @developer = Developer.new(developer_params)

    if @developer.save
      render json: @developer, status: :created, location: @developer
    else
      render json: @developer.errors, status: :unprocessable_entity
    end
  end

  # PATCH/PUT /developers/1
  def update
    if @developer.update(developer_params)
      render json: @developer
    else
      render json: @developer.errors, status: :unprocessable_entity
    end
  end

  # DELETE /developers/1
  def destroy
    @developer.destroy
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_developer
      @developer = Developer.find(params[:id])
    end

    # Only allow a list of trusted parameters through.
    def developer_params
      params.require(:developer).permit(:full_name, :email, :mobile)
    end
end
 

Схема объединения таблиц:

 class AddHabtmForTeamsAndDevelopers < ActiveRecord::Migration[6.1]
  def change
    create_table :teams_developers, id: false do |t|
      t.belongs_to :team
      t.belongs_to :developer
    end
  end
end
 

Ответ №1:

По умолчанию has_and_belongs_to_many ожидается имя таблицы с объединенными именами моделей в алфавитном порядке, так и должно быть developers_teams .

Вы можете переопределить соглашение по умолчанию join_table , установив параметр:

 has_and_belongs_to_many :teams, join_table: 'teams_developers'
 

Теперь причина, по которой он вообще смотрит на developers_team таблицу, заключается в том, что rails хочет удалить все записи объединения в таблице объединения, ссылающиеся на удаляемую запись.

Комментарии:

1. Небольшая синтаксическая ошибка с в конце, но в остальном отлично работает! Огромное спасибо!

2. Ха, как это тебя угораздило! xD Исправлено. Однако одно замечание — на самом деле нет причин изменять значение по умолчанию здесь, не так ли? В подобных случаях предпочтительнее просто следовать соглашению, поэтому я бы предпочел переименовать таблицу 🙂 (То есть, если я когда-нибудь снова воспользуюсь HABTM, в чем я действительно сомневаюсь!)

3. Конечно, я не знал о соглашении об именах во время его создания, и это скорее тестовый проект, чтобы выяснить, как работает rails. Но я буду иметь это в виду в следующий раз.