Внешний ключ по запросу Laravel & Vue - PullRequest
0 голосов
/ 15 сентября 2018

Я использую одноуровневый бэкэнд с Vue-интерфейсом.Они связаны через API.Я пытался выяснить, как правильно отправить форму для модели, которая имеет отношение foreign_key к родительской модели.

Вот отношения

  1. У пользователя много задач
  2. Задача принадлежит пользователю
  3. У клиента много заданий
  4. Задание принадлежит клиенту
  5. Заданий и заданий много-много
  6. У пользователя и клиента нет прямых отношений

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

* Пример

public function store(Request $request)
    {
        $data = $request->validate([
            'title' => 'required|string',
            'completed' => 'required|boolean',
        ]);
        $todo = Todo::create([
            'user_id' => auth()->user()->id,
            'title' => $request->title,
            'completed' => $request->completed,
        ]);
        return response($todo, 201);
    }

Но когда я пытаюсь сделать то же самое для моегоклиент я получаю 500 внутренняя ошибка сервера ..

Итак, вот рабочий процесс

На моем внешнем интерфейсе в компоненте AddEngagment.vue

<template>
  <div class="page-wrapper mt-1">
    <div class="add-engagement container">
      <div class="card-body bg-light border-primary mb-2">
        <h4 class="text-left text-primary m-0"><i class="mr-3 far fa-folder-open"></i>New Engagement</h4>
      </div>
        <form @submit.prevent="addEngagement" class="d-flex-column justify-content-center">
          <div class="form-group">
            <select class="form-control mb-3" id="type" v-model="engagement.return_type">
              <option v-for="type in types" :key="type.id" :value="type">{{ type }}</option>
            </select>
            <input type="text" class="form-control mb-3" placeholder="Year" v-model="engagement.year">
            <input type="text" class="form-control mb-3" placeholder="Assign To" v-model="engagement.assigned_to">
            <input type="text" class="form-control mb-3" placeholder="Status" v-model="engagement.status">

            <button type="submit" class="btn btn-lg btn-primary d-flex justify-content-start">Create</button>
          </div>
        </form>
      </div>  
  </div>
</template>

<script>


export default {
  name: 'add-engagement',
  data() {
    return {
      engagement: {
        return_type: null,
        year: '',
        assigned_to: '',
        status: '',
      },
      types: [ 
        'Choose Return Type...', 
        '1040', 
        '1120',
      ],
    }
  },
   methods: {
    addEngagement(e) {
      if(!this.engagement.return_type || !this.engagement.year ){
        return
      } else {
        this.$store.dispatch('addEngagement', {
          id: this.idForEngagement,
          return_type: this.engagement.return_type,
          year: this.engagement.year,
          assigned_to: this.engagement.assigned_to,
          status: this.engagement.status,
        })
        e.preventDefault();
      }
      e.preventDefault();
      this.engagement = "" 
      this.idForEngagement++
      this.$router.push('/engagements')
    },
  },
  created: function() {
    this.engagement.return_type = this.types[0]
  },

}
</script>

Я фиксируюданные во входных данных и затем отправка хранилища для действия addEngagement

Теперь в URL для компонента AddEngagement.vue у меня есть client_id, показанный ниже

add-engagement/{client_id}

Это хранилище.JS действие для addEngagement

addEngagement(context, engagement) {
      axios.post(('/engagements'), {
        return_type: engagement.return_type,
        year: engagement.year,
        assigned_to: engagement.assigned_to,
        status: engagement.status,
        done: false
      })
      .then(response => {
        context.commit('getClientEngagement', response.data)
      })
      .catch(error => {
        console.log(error)
      })
    },

Итак, он отправляет запрос my / engagement в файл маршрута laravel api, как показано ниже

Route::post('/engagements', 'EngagementsController@store');

, а затем переходит к EngagementsController для запуска метода store ниже

public function store($client_id, Request $request)
    {
        $data = $request->validate([
            'return_type' => 'required|string',
            'year' => 'required|string',
            'status' => 'required|string',
            'assigned_to' => 'required|string',
            'done' => 'required|boolean'
        ]);

        $engagement = Engagement::create([
            'return_type' => $request->return_type,
            'year' => $request->year,
            'assigned_to' => $request->assigned_to,
            'status' => $request->status,
            'done' => $request->done,
            + [
                'client_id' => $client_id
            ]
        ]);

        return response($engagement, 201);
    }

На этом этапе я получаю свою ошибку, и я думаю, что это связано с $client_id, который я безуспешно пытался отформатировать.Когда в URL-адресе хранится client_id во внешнем интерфейсе для запроса на публикацию, я не знаю, как эти данные передаются в laravel, чтобы он знал, какому клиенту будет назначен внешний ключ client_id.

1 Ответ

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

Прежде всего:

$engagement = Engagement::create([
            'return_type' => $request->return_type,
            'year' => $request->year,
            'assigned_to' => $request->assigned_to,
            'status' => $request->status,
            'done' => $request->done,
            + [
                'client_id' => $client_id
            ]
        ]);

почему существует этот массив +[...]? Не имеет смысла для меня ...

Но ошибка 500 Server, скорее всего, является результатом вашего ложного запроса (что делают большинство 500).

Если это ваше определение маршрута:

Route::post('/engagements', 'EngagementsController@store');

Это заголовок метода:

public function store($client_id, Request $request)

А ваш запрос на отправку следующий:

axios.post(('/engagements'), {
        return_type: engagement.return_type,
        year: engagement.year,
        assigned_to: engagement.assigned_to,
        status: engagement.status,
        done: false
      })

Вы заметите, что определение функции отличается от вашего маршрута. В функции вы ожидаете параметр 'client_id', который не известен по маршруту. Поэтому, чтобы решить эту проблему, поместите ваш client_id в тело запроса Post (например, под done: false) и удалите параметр из определения функции.

...