4ndro1d 4ndro1d - 2 months ago 25
PHP Question

Dealing with Eloquent relationships in Laravel 5.3

I have the following tables created using

Schema
s:

Schema::create('typen', function (Blueprint $table) {
$table->increments('id');
$table->string('name')->unique();
});

Schema::create('auktionen', function (Blueprint $table) {
$table->increments('id');
$table->integer('typ')->unsigned();

$table->foreign('typ')->references('id')->on('typen');
});


The table
typen
is only created once at contains fixed values:

Typen
id| name
1 | Typ 1
2 | Typ 2
...


Those values are constant, no more will be added during the application lifetime. So every
Auktion
I create should be associated with one
Typ
.
I created the model for
Auktion
and thought of it as a one-to-one relationship (is this correct?).

I would like to create an Auktion with a given Typ using Eloquent queries like this:

$thetyp = App\Typ::where("id", "=", 1)->first();
$auktion->typ()->associate($thetyp);


and fetch the
name
of the
Typ
of my
Auktion
:

$auktion->typ->name;


Currently my model looks like this for
Auktion
:

public function typ()
{
return $this->hasOne('App\Typ', 'typ');
}


which is not working. I already tried setting different relationships but I just end in different error codes ranging from undefined methods
(associate()
to an error where an SQL statement failed trying to update my
typen
table (when using
save()
- which I really do not want to).

Can someone clarify this problem for me and explain which relationship I have to use?

EDIT1: As mentioned in a comment I already tried using
belongsTo
in
Auktion
model

public function typ()
{
return $this->belongsTo('App\Typ', 'typ');
}


which results in
Undefined property: App\Auktion::$typ
when calling

$thetyp = App\Typ::where("id", "=", 1)->first();
$auktion->typ()->save($thetyp);


and when calling
$auktion->typ->name;
in

Trying to get property of non-object


EDIT2:

I just figured that

echo $auktion->typ()->first()->name;


is indeed working. But referring to this answer this should be the same as

echo $auktion->typ->name;


What exactly am i doing wrong?

EDIT3:

I tried using suggested code:

$thetyp = App\Typ::find($typ);
$auktion->typ->save($thetyp);


After I navigated to the view ehere I run the code I got this:

enter image description here

I got this the second time today, somwhow out of nowhere

Answer

Here is some code enhancement:

 $thetyp = App\Typ::where("id", "=", 1)->first();
 $auktion->typ()->save($thetyp);

To:

//Will return null if Model is not found
$thetyp = App\Typ::find(1);
//You actually have to retrieve the relationship, because calling typ()
//will only retrieve the Relationship query
$auktion->typ()->get()->save($thetyp);

The problem is that the relationship is defined backwards. You need to make Auction belongTo Type, and change Type to hasMany Auctions. The statement would read:

"A Type has many Auctions. An Auction has one Type".

Here are the classes (in English, sorry, my German is bad :( so I just did it in English) with the migrations:

-Auction class:

class Auction extends Model
{
    protected $table = 'auction';

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

-Auction migration:

Schema::create('auction', function(Blueprint $table){

$table->increments('id');
$table->integer('type_id')->references('id')->on('type')->nullable();
$table->string('title')->nullable();
$table->string('description')->nullable();

$table->timestamps();

});

-Type class:

class Type extends Model
{
    protected $table = 'type';

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

-Type migration:

 Schema::create('type', function(Blueprint $table){

      $table->increments('id');
      $table->string('name');

      $table->timestamps();
 });

First, you can create a Type object (or insert it with a query) so we can have a Type row that we can relate to an Auction object/entry, and do the following:

//Example of Type obj creation

$type = new Type();
$type->name = 'Type #1';
//Don't forget to save
$type->save();

//OR find/retrieve a Type obj

//Where $id is the id of the Type obj, else the obj will be null
$type = Type::find($id);

$auction = new Auction();

$auction->title = 'Title #1';
$auction->description = 'Test description';

$auction->type_id = $type->id;

//Don't forget to save
$auction->save();

Now later in your code, whenever you are using an Auction object and you want to retrieve the associated type (if any), you can use:

$type = $auction->type()->get();

Which will return the instance of Type, and you will be able to retrieve the property name like so:

$type->name

I hope this helps! Let me know if you have any more questions!