Объединить две таблицы базы данных в Laravel контроллер - PullRequest
1 голос
/ 29 февраля 2020

У меня есть две таблицы, которые я хочу объединить в контроллере - мысль_journal_entries и эмоции. Запись в журнале мыслей может содержать много эмоций, а внешний ключ в таблице мысли_джорна_данных - em_id.

Это пример записи в журнале мыслей, где пользователь выбирает эмоции с идентификатором 1, 3, 5

enter image description here

Это таблица эмоций

enter image description here

Это метод, который я использую для хранить данные в моей таблице мыслей_журналов

public function store(Request $request)
    {
        $this->validate($request, [
            'thought_entry' => 'required'
        ]);

        $entry = new ThoughtJournalEntry;
        $entry->user_id = auth()->user()->id;
        $entry['entry_date'] = date('Y-m-d H:i');
        $entry->thought = $request->input('thought_entry');
        $entry->em_id = $request->has('emotions') ? $request->get('emotions') : [];
        $entry->tt_id = $request->has('thinking_traps') ? $request->get('thinking_traps') : [];
        $entry->balanced_thought = $request->input('balanced_thought');
        $entry->save();

        return redirect('/dashboard');
    }

Ответы [ 3 ]

1 голос
/ 29 февраля 2020

В вашем примере em_id столбец это не внешний ключ, это строковый столбец, как я вижу. Следовательно, вы не можете выполнить запрос JOIN для этих таблиц. В вашем случае я могу порекомендовать создать третью таблицу thought_journal_entry_emotions.

Вот пример кода для файла миграции 2020_02_29_143059_create_thought_journal_entry_emotions_table.php:

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateThoughtJournalEntryEmotionsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('thought_journal_entry_emotions', function (Blueprint $table) {
            $table->integer('thought_journal_entry_id')->unsigned();
            $table->integer('emotion_id')->unsigned();

            $table->foreign('thought_journal_entry_id')
                ->references('id')
                ->on('thought_journal_entries')
                ->onUpdate('cascade')
                ->onDelete('cascade');

            $table->foreign('emotion_id')
                ->references('id')
                ->on('emotions')
                ->onUpdate('cascade')
                ->onDelete('cascade');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('thought_journal_entry_emotions');
    }
}

Затем вам нужно добавить отношения к вашим моделям Emotion и ThoughtJournalEntry.

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Emotion extends Model
{
    public function thoughtJournalEntries() {
        return $this->belongsToMany(ThoughtJournalEntry::class, 'thought_journal_entry_emotions',
            'emotion_id', 'thought_journal_entry_id');
    }
}
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class ThoughtJournalEntry extends Model
{
    public function emotions() {
        return $this->belongsToMany(Emotion::class, 'thought_journal_entry_emotions',
            'thought_journal_entry_id', 'emotion_id');
    }
}

После этого вы можете присоединить Emotions к ThoughtJournalEntry в вашем контроллере, используя этот код:

$thoughtJournalEntry = ThoughtJournalEntry::find(1);
$emotion1 = Emotion::find(1);
$emotion2 = Emotion::find(2);
$emotion3 = Emotion::find(3);
$thoughtJournalEntry->emotions()->sync([$emotion1->id, $emotion2->id, $emotion3->id]);

И, наконец, Вы можете загрузить ThoughtJournalEntry с Emotions в свой контроллер, используя этот код:

$thoughtJournalEntry = ThoughtJournalEntry::with('emotions')->find(1);
dd($thoughtJournalEntry);

enter image description here

Если вы хотите проверить и сохранить Emotions Связи, вы должны обновить ваш store() метод (добавить новое правило проверки и sync()). Вот пример:

    public function store(Request $request)
    {
        $this->validate($request, [
            'thought_entry' => 'required',
            'emotions' => 'array|max:3',
            'emotions.*' => 'exists:emotions,id'
        ]);

        $entry = new ThoughtJournalEntry;
        $entry->user_id = auth()->user()->id;
        $entry['entry_date'] = date('Y-m-d H:i');
        $entry->thought = $request->input('thought_entry');
        $entry->tt_id = $request->has('thinking_traps') ? $request->get('thinking_traps') : [];
        $entry->balanced_thought = $request->input('balanced_thought');
        $entry->save();

        $entry->emotions()->sync($request->get('emotions'));

        return redirect('/dashboard');
    }
0 голосов
/ 29 февраля 2020

это должно быть сделано с помощью Отношения ко многим * Многие , вы используете строку для хранения массива (это не mysql способ). (но похоже, что вы собираетесь чтобы сэкономить место в 'idea_journal_entries')

, вы можете использовать это так:

$journal_entries = thought_journal_entries::find(1);
$icon_ids = json_decode($journal_entries->em_id); // if this column is json
$emocions = emotions::whereIn('id', $icon_ids)->get();

, но при этом выполняются два карьера, которые могут повлиять на производительность БД и сервера

0 голосов
/ 29 февраля 2020

Присоединение к таблице будет немного сложнее, поскольку эталонное значение отсутствует. Но если вы пытаетесь получить имена эмоций от использования идентификатора, хранящегося в массиве. Сначала вам нужно сохранить массив эмоций в переменной. $em = ["1","3","5"]

$em = ["1","3","5"];
foreach ($em as $e) {
  $emotions = Emotions::find($e * 1); //am using * 1 just make sure its int
  $emotions->em_name;  
}

Надеюсь, это поможет.

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