Error when relating tables in laravel 5.5

2

Veran I want to do with laravel 3 tables: Plants, User and Comments. The story is that a user can write comments about the plants to ask or answer questions about the plant.

Migration of the Plants table:

<?php

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

class CreatePlantasTable extends Migration{
    public function up(){
        Schema::create('plantas', function (Blueprint $table) {
            $table->increments('id');
            $table->string('nombre'); // Nombre de la planta.
            $table->string('tamaño'); // Clasifica segun si es arbol, arbusto o hierba. 
            $table->string('flor'); // Si tiene o no flor.
            $table->string('hoja'); // Si es de hoja caduca o perenne.
            $table->text('descripcion'); // Caracteristicas del vegetal.
        });
    }

    public function down(){
        Schema::dropIfExists('plantas');
    }
}

Migration of the user table:

<?php

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

class CreateUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('email')->unique();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });
    }

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

And the migration of the comment table:

<?php

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

class CreateComentariosTable extends Migration{
    public function up(){
        Schema::create('comentarios', function (Blueprint $table){
            $table->increments('id');
            $table->unsignedInteger('usuario'); // Primero creas la variable. Luego creas la relación foranea.
            $table->foreign('usuario')->references('id')->on('users');
            $table->unsignedInteger('planta'); // Primero creas la variable. Luego creas la relación foranea.
            $table->foreign('planta')->references('id')->on('plantas');
            $table->text('comentario');
        });
    }

    public function down(){
        Schema::dropIfExists('comentarios');
    }
}

The index.blade.php code:

@extends('layouts.app')
@section('content')
<div class="row">
    <div class="col-md-8 col-md-offset-2">
    <h1 class="text-center text-mute"> {{ __("Plantas") }} </h1>
        @forelse($planta as $plantas)
        <div class="panel panel-default">
            <div class="panel-heading">
                <h3><a href="plantas/{{ $plantas->id }}">{{ $plantas->nombre }}</a></h3>
                <span class="pull-right"> {{ __("Comentarios") }}: {{ $plantas->comentarios->count() }} </span>
            </div>
            <div style="background-color:#00AA00; color:#000000;" class="panel-body">
                <h4>{{ $plantas->descripcion }}</h4>
            </div>
            <div class="panel-body">
                <b>Tamaño:</b> {{ $plantas->tamaño }}<br>
                <b>Flor:</b> {{ $plantas->flor }}<br>
                <b>Hoja:</b> {{ $plantas->hoja }}
            </div>
        </div>
    @empty
        <div class="alert alert-danger">
            {{ __("No hay ninguna planta en este momento") }}
        </div>
    @endforelse
    @if($planta->count())
    {{$planta->links()}}
    @endif
    </div>
</div>
@endsection

Now I'll show the relationships between the tables.

Plants:

class plantas extends Model{
    protected $table = 'plantas';

    protected $fillable = [
        'nombre', 'descripcion',
    ];

    public function comentarios(){
        return $this->hasMany(Comentario::class);
    }

User:

class User extends Authenticatable{
    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

    public function comentarios(){
        return $this->hasMany(Comentario::class);
    }
}

Comment:

class Comentario extends Model{
    protected $table = 'comentarios';

    protected $fillable = [
        'planta', 'usuario', 'comentario',
    ];

    public function vegetal(){
        return $this->belongsTo(plantas::class, 'planta');
    }

    public function usuario(){
        return $this->belongsTo(User::class, 'usuario');
    }
}

But here's the result:

Edit: Here I include the content of web.php:

<?php

Route::get('/', function (){
    $crawler = Goutte::request('GET', 'https://duckduckgo.com/html/?q=Laravel');
    $crawler->filter('.result__title .result__a')->each(function ($node) { dump($node->text()); });

    return view('Welcome');
});
Auth::routes();

Route::get('/home', 'HomeController@index')->name('home');

Route::get('/', 'PlantasController@index');

Route::get('/plantas/{planta}', 'PlantasController@show');

Also, here I bring the Plant controller:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\plantas;

class PlantasController extends Controller
{
    public function index() {
        $planta = Plantas::paginate(5);
        return view('vegetal.index', compact('planta'));
    }

    public function show(Plantas $planta){
    $comentario = $planta->comentarios()->with(['usuario'])->paginate(2);
    return view('plantas.detail', compact('plantas','comentarios'));
    }
}
    
asked by Miguel Alparez 10.02.2018 в 15:24
source

1 answer

1

to start your class names, variables and objects do not coincide with the typical conventions widely suggested by Laravel, which makes it difficult to understand the code and what you intend to do.

The models should be called in singular and preferably in the same language, also start in uppercase.

It can be in English:

  • User
  • Comment
  • Plant

They can be in Spanish:

  • User
  • Comment
  • Plant

When obtaining a collection of objects (of plants in this case), the variable should be called plural, and therefore, the foreach will have a consistent syntax:

On the controller

$plantas = Plantas::paginate(5);

In the view

@forelse($plantas as $planta)

    {{ $planta->nombre }}

Finally, you are not fully respecting PSR-2, which is used by Laravel.

Regarding the error that appears to you, from what I see it is simply that you did not define the foreign key when defining the comments relationship in the model of the plants:

class Planta extends Model
{
    protected $table = 'plantas';

    protected $fillable = [
        'nombre',
        'descripcion',
    ];

    public function comentarios()
    {
        return $this->hasMany(Comentario::class, 'planta');
    }
}
    
answered by 11.02.2018 / 16:21
source