Reputation: 2976
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
Upvotes: 0
Views: 263
Reputation: 1816
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!
Upvotes: 1
Reputation: 33058
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.
Upvotes: 1
Reputation: 3551
You can try this in your Auktion model
$thetyp = App\Typ::find(1);
$auktion->typ->save($thetyp);
Now fetch
$auktion->typ->name
Upvotes: 0