简体   繁体   中英

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:

在此处输入图片说明

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

Your second edit makes a lot of sense. Your method name is typ but that's also the name of the column. So when you use $auktion->typ() it's actually loading the relationship. When you use $auktion->typ it's grabbing the value of that column.

You need to either continue working this way using the parenthesis to load the relation and no parenthesis to grab the value of the column, or you can change the name of the column to something better such as typ_id which is ultimately what Laravel expects it to be and should save you from more similar headaches down the road.

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!

You can try this in your Auktion model

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

Now fetch

$auktion->typ->name

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM