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.
Existe uma solução rápida para isso.
Primeiro adicione uma chave estrangeira na função do VocVocabulary
modelotype
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 type
funçã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 VocType
modelo de segmentação . Além disso, você precisa alterar a chave estrangeira na tabela de VocVocabulary
de type_id
para 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.
deixe-me dizer algumas palavras