簡體   English   中英

調用未定義的方法 Illuminate\\Database\\Eloquent\\Relations\\BelongsTo::type() [Laravel]

[英]Call to undefined method Illuminate\\Database\\Eloquent\\Relations\\BelongsTo::type() [Laravel]

我正在嘗試制作一個 api ,它將在數據庫中創建該單詞后返回單詞的類型(名詞、代詞、動詞等)。 但是由於某種原因,當我的詞匯表 model 中明確定義了類型方法時,我收到“調用未定義方法 Illuminate\Database\Eloquent\Relations\BelongsTo::type()”錯誤。 我沒有使用多對多關系,而是一對多關系(這就是我使用 hasMany() 和 belongsTo 的原因)。 類型有很多詞匯,但詞匯只有一種類型和很多詞匯內容,詞匯內容只有一個與之相關的詞匯。 所以顯然沒有多對多的關系。 很明顯,我的問題不是Call to undefined method (laravel 5.2)的重復。 以下是應用程序的部分代碼。

第一個 model 是 model 類型,它允許我獲取類型的“內容”(此處未列出模型)和屬於特定類型的詞匯表。

型號代碼清單 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');
    }
}

這第二個 model 允許我在詞匯表中創建一個單詞,訪問它的“內容”、類型和類別。 這就是問題所在。

型號代碼清單 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');
    }
}

第三個 model 允許我創建詞匯表的內容並訪問它的父詞匯表。

模型代碼清單 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');
    }
}

這是 controller,我在其中調用詞匯表的 type() 方法。 基本上我有一個 html 表單,如果請求中沒有提供 id,則會創建一個詞匯表(如果語言是英語),它會向這個控制器的方法(postVocabularyAPI)發送一個發布請求。 然后,無論請求是否提供了 id,該方法都會為給定的 id 創建一個詞匯“內容”(如果沒有提供 id,則給定的 id 將是先前創建的詞匯的 id)。 然后 postVocabularyAPI 方法將返回一個 json 響應,其中包含詞匯表類型的 id。

控制器代碼清單 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)).'"}';

我收到一條錯誤消息

“呼叫成員 function type() on null”

這是不對的,因為數據庫已正確填充,所以我不應該得到 null 詞匯表。

有一個快速的解決方案。

首先在VocVocabulary model type function 中添加外鍵

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

然后去掉括號

echo $vocabularyContent->type->id;

但這不是做到這一點的標准方法。 您需要以標准方式設置您的關系,以幫助 Laravel 了解您的關系。

首先,您需要將 function 名稱更改為 model 名稱的 camelCase。 例如,由於您的類型 model 名稱是VocType ,因此您的type function 應更改為

public function type()

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

在這種情況下,您告訴 laravel function vocType的目標是VocType model。 此外,您需要將VocVocabulary表中的外鍵從type_id更改為voc_type_id 通過這種方式 Laravel 清楚地了解您的關系,否則您需要付出額外的努力來教 laravel 關於您的關系。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM