I'm on laravel 4.2, trying to get an objects associative relation yet for some reason I am getting null.
Models:
class Keg extends Eloquent {
protected $fillable = ['beer_distribution_id', 'status', 'keg_size'];
public function beer_distribution()
{
return $this->belongsTo('BeerDistribution');
}
}
class BeerDistribution extends Eloquent {
protected $fillable = ['beer_id', 'distributor_id'];
public function kegs()
{
return $this->hasMany('Keg');
}
}
My Query:
$distirbution = Keg::find($tap->keg_id)->beer_distribution
This query returns null: I know the keg object is found and I know that the object has the beer_distribution_id.
I tried specifying the foreign key in the model like so:
class Keg extends Eloquent {
protected $fillable = ['beer_distribution_id', 'status', 'keg_size'];
public function beer_distribution()
{
return $this->belongsTo('BeerDistribution', 'beer_distribution_id');
}
}
I thought that might be necessary since the Model is camel case.
I know this is super simple, and I am in fact querying many relations succesfully through out my application, but for some reason this one is not working. Any thoughts on what I might be missing?
The problem is the function name of the relationship. Laravel expects it to be in camel case: beerDistribution().
Change that and you should be good. (You don't have to specify the foreign key, Laravel will convert camelCase to snake_case)
Related
I am trying to return data from my database and I want it to include data from the related table. It is a one-to-many relationship. However I all I get is an error
Property [User] does not exist on this collection instance.
In my User model I have
//App\User.php
class User extends Authenticatable{
use Notifiable;
public function systems(){
return $this->hasMany(\App\Models\General\systems::class,'added_by','id');
}
The other model, called systems I have
//App\Models\General\systems.php
class systems extends Model
{
public function User(){
return $this->belongsTo(\App\User::class,'added_by','id');
}
In my controller I have
$this->systemsObject = new \App\Model\General\systems();
$systems = $this->systemsObject->get()->User;
according to the Laravel Documentation this should work but it isn't. I tried reversing the foreign key/local key parameters. I made the ->User uppercase, lowercase.
I have no idea what I am doing wrong
You need to iterate over the collection, for example:
$systems = $this->systemsObject->get();
foreach ($systems as $system) {
echo $system->User->name;
}
I've got Tag and Attendee Eloquent models, they are in many-to-many relation. Pivot table has also two more attributes – value_int and value_string. My Attendee model looks like this:
class Attendee extends Model
{
public $timestamps = false;
protected $fillable = [
'event_id'
];
public function tags() {
return $this->belongsToMany('App\Models\Tag', 'attendee_tag', 'attendee_id', 'tag_id')
->withPivot(['value_string', 'value_int']);
}
public function scoreTagValue($tag_id) {
return $this->tags->where('tag_id', '=', $tag_id)->first();
}
}
What I want is to obtain pivot values based on Attendee model and variable tag_id, so I've written scoreTagValue function, but it always returns null and I don't know why :( I'm calling it this way:
$attendee->scoreTagValue($tag_id). Thanks for your help :)
You need to access the relation, not the property:
public function scoreTagValue($tag_id) {
return $this->tags()->where('tag_id', '=', $tag_id)->first();
}
Also, according to the docs, withPivot() does not take an array, so:
->withPivot('value_string', 'value_int');
Suppose I have a Course model like this :
class Course extends Model
{
public $primaryKey = 'course_id';
protected $appends = ['teacher_name'];
public function getTeacherNameAttribute ()
{
$this->attributes['teacher_name'] = $this->teacher()->first()->full_name;
}
public function teacher ()
{
return $this->belongsTo('App\User', 'teacher', 'user_id');
}
}
And in the other hand there is a User model like this :
class User extends Authenticatable
{
public $primaryKey = 'user_id';
protected $appends = ['full_name'];
public function getFullNameAttribute ()
{
return $this->name . ' ' . $this->family;
}
public function course ()
{
return $this->hasMany('App\Course', 'teacher', 'user_id');
}
}
As you can see there is a hasMany relationship between those.
There is an full_name accessor in User model.
Now I want to add a teacher_name accessor to Course model that uses it's teacher relations and gets full_name of teacher and appends to Course always.
In fact I want whenever call a Course model, it's related teacher name included like other properties.
But every time , when call a Course model , I got this error :
exception 'ErrorException' with message 'Trying to get property of non-object' in D:\wamp\www\lms-api\app\Course.php:166
That refers to this line of Course model :
$this->attributes['teacher_name'] = $this->teacher()->first()->full_name;
I do not know how can I solve that and what is problem exactly.
Yikes some interesting answers here.
FYI to those coming after me- getFooAttribute() should return the data, and not modify the internal attributes array.
If you set a new value in the attributes array (that doesnt exist in this model's db schema) and then attempt to save the model, you'll hit a query exception.
It's worth reading up the laravel docs on attribute accessors/mutators for more info.
Furthermore, if you need to access a related object from within the model (like in an accessor) you ought to call $related = $this->getRelation('foo'); - note that if the relation isnt loaded (e.g., if you didnt fetch this object/collection with eager loaded relations) then $this->getRelation() could return null, but crucially if it is loaded, it won't run the same query(ies) to fetch the data again. So couple that with if (!$this->relationLoaded('foo')) { $this->loadRelation('foo'); }. You can then interact with the related object/collection as normal.
$this->attributes['teacher_name'] = $this->teacher()->first()->full_name;
Should be
$this->attributes['teacher_name'] = $this->teacher->full_name;
First thing is that you want to reference the relationship, so loose the brackets (), and because the relationship is belongsTo, you will have one user / teacher returned. So you don't need the first().
We haven't seen your fields but probably you will have to change:
return $this->belongsTo('App\User', 'teacher', 'user_id');
to
return $this->belongsTo('App\User', 'foreign_key', 'other_key');
where foreign_key and other_key are the primary keys that you need to make the join on.
Check this link from the documentation for reference:
https://laravel.com/docs/5.4/eloquent-relationships#one-to-many-inverse
the right way to do this is:
COURSE
public function setTeacherNameAttribute ()
{
$this->attributes['teacher_name'] = $this->teacher->full_name;
}
100% working for me.
I have one to one relationship between Order and Shipment. I have to add the accessor of shipments table column from orders table.
function getOrderNoAttribute()
{
$appendText = "OR100";
if($this->orderShipment()->first()) {
$appendText = $this->orderShipment()->first()->is_shipping === 1 ? "ORE100" : "OR100";
}
return $appendText . $this->attributes['id'];
}
This error is only object data to array use or array data to object data use.
example::
$var->feild insted of $var[feild]
$var[feild] insted of $var->feild
You should use return for accessors . something like this :
public function getTeacherNameAttribute ()
{
return $this->teacher()->first()->full_name ?? '';
}
maybe a course hasn't teacher.
I am new to Laravel and am struggling with this:
Database - MSSQL existing DB schema cannot be modified as other software depends on it. (not sure if this is a problem or not)
Model/Table setup:
INFO_ALL Table - ID is primary key
PERSON Table - ID is foriegn key
ID's are hex values and I notice eloquent removes the 0x from the start of the value and am not sure if this is causing the relationship to fail or not. example: in the DB I see 0x123456789 in my returned eloquent data I see 123456789
Person Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Person extends Model
{
protected $table = 'PERSON';
protected $primaryKey = 'ID';
public $incrementing = false;
public $timestamps = false;
public function info_all(){
return $this->belongsTo(Info_All::class, 'ID', 'ID');
}
}
Info Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Info_All extends Model
{
protected $table = 'INFO_ALL';
protected $primaryKey = 'ID';
public $incrementing = false;
public $timestamps = false;
public function person(){
return $this->hasOne(Person::class, 'ID', 'ID');
}
}
How I am testing the relationship:
php artisan tinker
$person = App\Person::first();
$person->info;
NULL
php artisan tinker
$info= App\Info::first();
$info->person;
NULL
I know this relationship exists in the DB and I can manuualy get them together with a query but the relationship feature of this framework would really be nice to get figured out.
Beign new to Laravel there are a few things I am unsure about, like if the third argument in the realationship is neccesary since I am declaring the $primaryKey. I declared the $primarykey in the first model because I assummed it is case sensative and my table has ID not id. That being said, I have been stuck on this for a couple days and feel like I have tested everything in every different combination.
Any help is appreciated.
Your relation is defined incorrectly. Try by adding following relation:
Person Model
public function info()
{
return $this->hasOne(Info_All::class, 'ID', 'ID');
}
Info_All model
public function person()
{
return $this->belongsTo(Person::class, 'ID', 'ID');
}
Then try it out in tinker:
$person = App\Person::first();
$person->info;
I am not sure but if eloquent removes the 0x from the start of the value then it can also cause the problem.
Try by removing 0x from your tables.
I have a table called champ_sales which contains champions that belong to table champions. I've set up my models properly, and I'm trying to query in the exact same way the documentation here: http://laravel.com/docs/eloquent#querying-relations states, but it's not working.
class ChampSales extends Eloquent {
protected $table = 'champ_sales';
public function champ(){
return $this->belongsTo('Champion');
}
}
class Champion extends Eloquent {
protected $table = 'champions';
public function skins(){
return $this->hasMany('Skin');
}
//relevent relation here:
public function championOnSale(){
return $this->hasMany('ChampSales');
}
public function skinOnSale(){
return $this->hasMany('SkinSales');
}
}
My query: Find start_date in table champions for id=2
$champsales = ChampSales::find(2);
echo $champsales->champ->start_date;
Running this gives me a vague error that says "Trying to get property of non-object". I'm not really sure what I've done wrong, followed the documentation to the dot.
I just fixed it. I defined the local key and foreign key in champ(). I thought the laravel naming convention would pick that up fine, but I guess not.
class ChampSales extends Eloquent {
protected $table = 'champ_sales';
public function champ(){
return $this->belongsTo('Champion', 'champion_id', 'id');
}
}