Вызов неопределенного метода Illuminate \\ Database \\ Eloquent \\ Relations \\ BelongsTo :: type () [Laravel] - PullRequest
0 голосов
/ 30 сентября 2019

Я пытаюсь создать API, который будет возвращать тип слова (существительное, местоимение, глагол и т. Д.) После создания этого слова в базе данных. Но по какой-то причине я получаю ошибку «Вызов неопределенного метода Illuminate \ Database \ Eloquent \ Relations \ BelongsTo :: type ()», когда метод type четко определен в моей модели словаря. Я не использую отношения «многие ко многим», а «один ко многим» (вот почему я использую hasMany () и serveTo). Тип имеет много словарей, но у словаря есть только один тип и много словаря, а у словаря есть только один словарь, с которым он связан. Так что, очевидно, отношения между многими и многими. Ясно, что мой вопрос не является дубликатом вызова неопределенного метода (уровень 5.2) . Вот части кода для приложения.

Первая модель - это модель типов, с помощью которой можно получить «содержимое» типа (модель не указана здесь) и словари, принадлежащие конкретному типу. .

модель-код-листинг 1: VocType.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class VocType extends Model
{
    public function contents()
    {
        return $this->hasMany('App\VocTypeContent');
    }

    public function vocabularies()
    {
        return $this->hasMany('App\VocVocabulary');
    }
}

эта вторая модель позволяет мне создать слово в словарной таблице и получить доступ к его "содержимому", тип и категория. Вот в чем проблема.

модель-код-листинг 2: VocVocabulary.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class VocVocabulary extends Model
{
    protected $fillable = ['voc_category_id','type_id', 'name', 'context', 'picture'];
    public $timestamps = false;

    public function contents()
    {
        return $this->hasMany('App\VocVocabularyContent');
    }

    public function type()
    {
        return $this->belongsTo('App\VocType');
    }

    public function category()
    {
        return $this->belongsTo('App\VocCategory');
    }
}

Третья модель позволяет мне создавать содержимое словаряи получить к нему доступ к родительскому словарю.

модель-код-листинг 3: VocVocabularyContent.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class VocVocabularyContent extends Model
{
    protected $fillable = ['voc_vocabulary_id','lang_id', 'content', 'context', 'romanization', 'pronunciation', 'audio'];
    public $timestamps = false;

    public function vocabulary()
    {
        return $this->belongsTo('App\VocVocabulary');
    }
}

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

листинг кода миграции 1: create_voc_types_table.php

<?php

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

class CreateVocTypesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('voc_types', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('abbreviation');
        });
    }

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

листинг кода миграции 2: create_voc_vocabularies_table.php

<?php

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

class CreateVocVocabulariesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('voc_vocabularies', function (Blueprint $table) {
            $table->increments('id');
            $table->unsignedInteger('cat_id');
            $table->unsignedInteger('type_id');
            $table->foreign('cat_id')->references('id')->on('voc_categories')->onDelete('cascade');
            $table->foreign('type_id')->references('id')->on('voc_types')->onDelete('cascade');
            $table->string('name');
            $table->string('context');
            $table->string('picture');
        });
    }

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

список кодов миграции 3: create_voc_vocabulary_contents_table.php

<?php

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

class CreateVocVocabularyContentsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('voc_vocabulary_contents', function (Blueprint $table) {
            $table->primary(['voc_id', 'lang_id']);
            $table->unsignedInteger('voc_id');
            $table->unsignedInteger('lang_id');
            $table->foreign('voc_id')->references('id')->on('voc_vocabularies')->onDelete('cascade');
            $table->foreign('lang_id')->references('id')->on('languages')->onDelete('cascade');
            $table->string('content');
            $table->string('context');
            $table->string('romanization');
            $table->string('pronunciation');
            $table->string('audio');
        });
    }

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

Это контроллер, в котором я вызываю метод словаря типа (). в основном у меня есть html-форма, которая отправляет запрос post в метод этого контроллера (postVocabularyAPI), если в запросе не указан идентификатор, будет создан словарь (если язык английский). Затем, независимо от того, предоставляется ли идентификатор в запросе, метод создаст словарь «контент» для данного идентификатора (если идентификатор не указан, данный идентификатор будет идентификатором ранее созданного словаря). Затем метод postVocabularyAPI вернет ответ json, содержащий идентификатор типа словаря.

контроллер-код-листинг 1: Vocabulearn.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Language;
use App\VocTheme;
use App\VocCategory;
use App\VocCategoryContent;
use App\VocVocabulary;
use App\VocVocabularyContent;
use App\VocType;

class Vocabulearn extends Controller
{

    //other methods above

    public function postVocabularyAPI(Request $request, $language, $theme, $category){

        $vocabulary_id = $request->vocabulary_id;
        if($vocabulary_id === NULL){
            if($language == "english"){
                $vocabulary = VocVocabulary::create([
                    'voc_category_id'   => VocCategory::where("slug", $category)->get()->first()->id,
                    'type_id'           => VocType::where("abbreviation", $request->type)->get()->first()->id,
                    'name'              => ucfirst(addslashes($request->translation)),
                    'context'           => $request->context,
                    'picture'           => ''
                ]);
                $vocabulary_id = $vocabulary->id;
            } else {
                echo '{"success":false, "message":"Create first the English Vocabulary"}';
            }
        }

        $vocabularyContent = VocVocabularyContent::where('lang_id', '=', Language::where("slug", $language)->get()->first()->id)
        ->where('voc_vocabulary_id', '=', $vocabulary_id)
        ->first();

        if($vocabularyContent !== NULL){
            $vocabularies = DB::table('voc_vocabulary_contents')
            ->where('lang_id', '=', Language::where("slug", $language)->get()->first()->id)
            ->where('voc_vocabulary_id', '=', $vocabulary_id)
            ->delete();
        }

        $vocabularyContent = VocVocabularyContent::create([
            'voc_vocabulary_id' => $vocabulary_id,
            'lang_id' => Language::where("slug", $language)->get()->first()->id,
            'content' => ucfirst(addslashes($translation)),
            'context' => addslashes($context),
            'romanization' => strtolower(addslashes($romanization)),
            'pronunciation' => $pronunciation,
            'audio' => $request->audio
        ]);

        echo '{"success":true, "type":"'.stripslashes(html_entity_decode($vocabularyContent->vocabulary()->type()->id)).'"}';
    }
}

это дает мне

"вызов неопределенного метода Illuminate \ Database \ Eloquent \ Relations \ BelongsTo :: type ()"

, даже когда я изменяю

echo '{"success":true, "type":"'.stripslashes(html_entity_decode($vocabularyContent->vocabulary()->type()->id)).'"}';

от

echo '{"success":true, "type":"'.stripslashes(html_entity_decode($vocabularyContent->vocabulary()->get()->first()->type()->id)).'"}';

Я получаю сообщение об ошибке

"Вызов функции-члена типа () со значением NULL"

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

1 Ответ

1 голос
/ 30 сентября 2019

Существует быстрое решение для этого.

Сначала добавьте внешний ключ в VocVocabulary модель type функция

public function type()
{
    return $this->belongsTo('App\VocType', 'type_id');
}

А затем удалите парантез

echo $vocabularyContent->type->id;

Но это не стандартный способ сделать это. Вам нужно настроить ваши отношения стандартными способами, чтобы помочь Laravel понять ваши отношения.

Сначала вам нужно изменить имя функции как camelCase имени модели. Например, имя модели вашего типа равно VocType, поэтому ваша функция type должна быть изменена на

public function type()

На

public function vocType()
{
 return $this->belongsTo('App\VocType'); //you don't need a foreign key here
}

В этом случае вы говорите Laravel, что функцияvocType нацелен на VocType модель. Кроме того, вам нужно изменить внешний ключ в таблице VocVocabulary с type_id на voc_type_id. Таким образом, Laravel четко понимает ваши отношения, в противном случае вам нужно приложить дополнительные усилия, чтобы научить laravel о ваших отношениях.

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