Chamada para método indefinido Illuminate \\ Database \\ Eloquent \\ Relations \\ BelongsTo :: type () [Laravel]

Paiku Han

Estou tentando fazer uma api que retornará o tipo de uma palavra (substantivo, pronome, verbo, etc.) depois de criar essa palavra no banco de dados. Mas, por algum motivo, estou recebendo um erro "Chamada para método indefinido Illuminate \ Database \ Eloquent \ Relations \ BelongsTo :: type ()" quando o método type está claramente definido em meu modelo de vocabulário. Não estou usando um relacionamento muitos para muitos, mas um para muitos (é por isso que estou usando hasMany () e belongsTo). O tipo tem muitos vocabulários, mas o vocabulário tem apenas um tipo e muitos VocabularyContents e o VocabularyContent tem apenas um vocabulário ao qual está relacionado. Claramente, nenhum relacionamento de muitos para muitos. Então, claramente, minha pergunta não é uma duplicata do método Call to undefined (laravel 5.2) . Aqui estão partes do código do aplicativo.

O primeiro modelo é o modelo de tipo que me permite obter os "conteúdos" de um tipo (modelo não listado aqui) e os vocabulários que pertencem a um tipo específico.

listagem de código de modelo 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');
    }
}

este segundo modelo me permite criar uma palavra na tabela de vocabulário acessando seu "conteúdo", tipo e categoria. É aqui que reside o problema.

listagem de código de modelo 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');
    }
}

O terceiro modelo me permite criar o conteúdo de um vocabulário e acessar o vocabulário pai.

listagem de código de modelo 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');
    }
}

abaixo estão as três migrações usadas para os modelos listados acima.

lista de códigos de migração 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');
    }
}

lista de códigos de migração 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');
    }
}

lista de códigos de migração 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');
    }
}

Este é o controlador para o qual estou chamando o método type () de vocabulário. basicamente eu tenho um formulário html que envia uma solicitação de postagem para o método deste controlador (postVocabularyAPI) se nenhum id for fornecido na solicitação, um vocabulário será criado (se o idioma for inglês). Então, quer um id seja fornecido ou não com a solicitação, o método criará um "conteúdo" de vocabulário para o id fornecido (se nenhum id for fornecido, o id fornecido será o id do vocabulário criado anteriormente). Então, o método postVocabularyAPI retornará uma resposta json contendo o id do tipo de vocabulário.

lista de código do controlador 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)).'"}';
    }
}

fazer isso me dá um

"Chamada para método indefinido Illuminate \ Database \ Eloquent \ Relations \ BelongsTo :: type ()"

mesmo quando eu mudo

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

de

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

Recebo um erro ao declarar

"Chamada para um tipo de função de membro () em nulo"

o que não está certo porque o banco de dados foi preenchido corretamente, então eu não deveria estar obtendo um vocabulário nulo.

Zain Farooq

Existe uma solução rápida para isso.

Primeiro adicione uma chave estrangeira na função do VocVocabularymodelotype

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

E, em seguida, remova a parêntese

echo $vocabularyContent->type->id;

Mas não é a maneira padrão de fazer isso. Você precisa configurar seus relacionamentos de maneira padrão para ajudar o Laravel a entender seus relacionamentos.

Primeiro você precisa alterar o nome da função como camelCase do nome do modelo. Por exemplo, como seu nome de modelo de tipo é VocType, sua typefunção deve ser alterada como

public function type()

Para

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

Nesse caso, você está dizendo a laravel que a função vocTypeé o VocTypemodelo de segmentação . Além disso, você precisa alterar a chave estrangeira na tabela de VocVocabularyde type_idpara voc_type_id. Desta forma, o Laravel entende claramente o seu relacionamento, caso contrário, você precisa se esforçar para ensinar laravel sobre seus relacionamentos.

Este artigo é coletado da Internet.

Se houver alguma infração, entre em [email protected] Delete.

editar em
0

deixe-me dizer algumas palavras

0comentários
loginDepois de participar da revisão

Artigos relacionados

Chamada ao método indefinido Illuminate \ Database \ Eloquent \ Relations \ BelongsTo :: save ()

Chamada para método indefinido Illuminate \ Database \ Eloquent \ Builder :: sortByDesc ()

Chamada para método indefinido Illuminate \ Database \ Eloquent \ Builder :: mapInto ()

Laravel 7.6 Chamada para método indefinido Illuminate \ Database \ Eloquent \ Builder :: appends ()

Laravel 5.3 Chamada para método indefinido Illuminate \ Database \ Eloquent \ Factory :: state ()

Laravel 5 Chamada para método indefinido Illuminate \ Database \ Eloquent \ Collection :: tags ();

Tentando preencher a tabela intermediária usando attach (), mas obtendo "Chamada para método indefinido Illuminate \ Database \ Eloquent \ Relations \ HasMany :: attach ()"

Chamada ao método indefinido Illuminate \ Database \ Eloquent \ Builder :: save ()

Laravel API ResourceCollection - Chamada ao método indefinido Illuminate \ Database \ Eloquent \ Builder :: mapInto ()

laravel APi resource Chamada para método indefinido Illuminate \ Database \ Query \ Builder :: mapInto ()

Como resolver Chamada para método indefinido Illuminate \ Database \ Query \ Builder :: Notice ()? (laravel 5.3)

Chamada para método indefinido Illuminate \\ Database \\ Schema \\ Blueprint :: increments ()

Chamada para método indefinido Illuminate \ Database \ Query \ Builder :: withTrashed ()

Chamada para método indefinido Illuminate \ Database \ Query \ Builder :: remember ()

Chamada para método indefinido Illuminate \ Database \ Query \ Builder :: withAccessToken ()

Chamada para método indefinido Illuminate \ Database \ Query \ Builder :: withAccessToken ()

Chamada para método indefinido Illuminate \ Database \ Query \ Builder :: exchangeges ()

Chamada para método indefinido Illuminate \ Database \ Query \ Builder :: tags ()

Chamada para método indefinido Illuminate \ Database \ Query \ Builder :: passageiros ()

Chamada para método indefinido Illuminate \ Database \ Query \ Builder :: getForeignKey ()

Chamada ao método indefinido Illuminate \ Database \ Eloquent \ Builder :: save () ao executar um comando de agendamento de tarefa do Laravel

Chamada ao método indefinido Illuminate \ Database \ Query \ Builder :: lists () quando propagando após atualizar para o Laravel 5.3

Propriedade indefinida: Illuminate \ Database \ Eloquent \ Relations \ BelongsTo :: $ center_name

Chamada para método indefinido Illuminate \ Database \ Eloquent \ Builder :: links () (Visualização: D: \ xampp \ htdocs \ mieaceh \ resources \ views \ shop.blade.php)

Chamada ao método indefinido Illuminate \ Database \ Query \ Builder :: notificar () Laravel 5.4

Laravel - Chamada ao método indefinido Illuminate \ Database \ Query \ Builder :: user ()

Chamada ao método indefinido Illuminate \ Database \ Query \ Builder :: map () no laravel 5.4

Laravel 5.4: Chamada ao método indefinido Illuminate / Database / Query / Builder :: getRelated ()

BadMethodCallException Chamada para método indefinido Illuminate \ Database \ Query \ Builder :: searchable ()