Laravel 5.1 belongsTo Trying to get property of non-object - laravel

I'm trying to echo out the name of the user in my article and I'm getting the ErrorException Trying to get property of non-object. Here is my code:
Model (I have a User model too):
1. News
class News extends Model
{
public function postedBy()
{
return $this->belongsTo('User');
}
protected $table = 'tcity_news';
protected $fillable = ['newsContent', 'newsTitle', 'postedBy'];
}
2. User
class User extends Model implements AuthenticatableContract,
AuthorizableContract,
CanResetPasswordContract
{
use Authenticatable, Authorizable, CanResetPassword;
protected $table = 'users';
protected $fillable = ['name', 'email', 'password'];
protected $hidden = ['password', 'remember_token'];
}
Controller:
public function showArticle($slug)
{
$article = News::where('slug', $slug)->firstOrFail();
return view('article', compact('article'));
}
Blade:
{{ $article->postedBy->name }}
When I try to remove name in the blade {{ $article->postedBy }} it echoes out the id, but when I try to add the ->name there it says Trying to get property of non-object but I have a field name in my table and User model. Am I missing something?
UPDATE: When I try what user dschu said which is {{ dd( $article->postedBy) }} , I get the id of the user.

The problem is that you seem to have the same name (postedBy) for your relationship and the field in you database.
You should have a field called user_id instead of postedBy (or userId to be consistent).

Related

Laravel: Multiple tables in one model

I have the following model for Users:
class User extends Authenticatable
{
use Notifiable;
protected $table = 'login_info';
/**
* 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 getDashboards()
{
return \DB::table('dashboard')
->select('type')
->where('id', Auth::id())
->orderBy('column', 'asc')
->get();
}
}
Users have different information in many tables
user info like name, office, dashboard,2FA etc
Is the way I do it now "best practice" (like the getDashboards function) for getting information from different tables?
Or should I create a model for each of the tables and then "join them" (hasMany, belongsToMany, and so on) for each of the tables?
EDIT:
I am now using models, but the result of the query is always an empty array.
class Dashboard extends Model
{
protected $table = 'dashboard';
public function user()
{
return $this->belongsTo(User::class,'user_id','id');
//user_id
}
}
user_id is the id of the user which is used in the login_info table.
And in the User class I have:
public function dashboards()
{
return $this->hasMany(Dashboard::class,'id','user_id');
}
In the login controller I have:
$user = \App\User::find(1);
$user->dashboards;
Anyone see what the problem could be?
Thanks for any help!
public function dashboards()
{return $this->hasMany(\App\Dashboard::class);
}
And in your Dashboard Model you do it this way
protected $casts = [
'user_id' => 'int',
];
public function user()
{
return $this->belongsTo(\App\User::class);
}
The more Laravel way is to rather created the related Dashboard model and use the eloquent relationships, and harness the features of the ORM. Nothing wrong to include an orderBy on the relationship if you always need ordering on that column.
class User extends Authenticatable
{
public function dashboards()
{
return $this->hasMany(Dashboard::class)
->orderBy('column', 'asc');
}
}
class Dashboard extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
}
You do not have to do anything in the model! Just refer to the model in the controller, for example:
User::where('id', Auth::id())->pluck('type');

BelongsToMany of Laravel 5.4 does not work

I am creating a table where it displays a list of requests, I have a relation between the ID's 'erp_createdid' and 'erp_productid'. To display the name of the products, I created a belongsToMany, in which I specify my two 'ID's'.
Order model
class Order extends Model
{
protected $table = 'erp_order';
protected $fillable = ['erp_createdid'];
protected $primaryKey = 'erp_orderid';
public function description()
{
return $this->belongsToMany('App\Description','erp_order_product', 'erp_createdid', 'erp_productid');
}
}
Description Model
class Description extends Model
{
protected $table = 'erp_product_description';
protected $primaryKey = 'erp_productid';
protected $fillable = ['erp_name'];
public $timestamps = false;
public function order()
{
return $this->belongsToMany('App\Order', 'erp_order_product', 'erp_createdid', 'erp_productid');
}
Table
<td>#foreach($orders->description as $des)
{{$des->erp_name}}
#endforeach
</td>
But the values in the table are not displayed, any suggestions?
I think you have the parameters on Order's belongsToMany in an incorrect order.
Try this:
public function description()
{
return $this->belongsToMany('App\Description','erp_order_product', 'erp_productid', 'erp_createdid');
}
Also try updating your foreach like this:
Oh OK, try this:
#foreach($orders as $order)
#foreach($order->description as $description)
{{ $description->erp_name }}
#endforeach
#endforeach

hasOne and belongsTo relation tables - laravel

My tables :
users :
id fname email
brands:
id title user_id_made
each user has many brands and each brand belongTo an user.
class Brand extends Model
{
protected $table = 'brands';
protected $fillable = array('title_fa',
'title_en','logo','user_id_made');
public function user()
{
return $this->hasOne('App\Models\User');
}
}
class User extends Authenticatable
{
use Notifiable;
protected $fillable = [
'fname' ,'lname' , 'username', 'email', 'password',
];
protected $hidden = [
'password', 'remember_token',
];
public function brand()
{
return $this->belongsTo('App\Models\Brand','user_id_made');
}
}
my code hasn't any output about users .
$data['brands'] = \DB::table('brands')->find(1);
var_dump($data['brands']);
return;
This will not load user. I will suggest you to use model instance in place of DB instance. if you want to load user with brands then you can use laravel's eager loading.
First in your Brand.php model
You need to pass the second argument as user_id_made to hasOne function otherwise it will assume it user_id.
public function user()
{
return $this->hasOne('App\Models\User','user_id_made');
}
You can do something like that.
$data['brands'] = Brand::with('user')->find(1);
Now If you will return $data['brands'] then it will return user information also.
Hope this will help.

Laravel default user_id attribute in Model

I have a model
class Foo extends Model
{
protected $fillable = [
'name',
'user_id'
];
}
I would like to set Auth::user()->id by default to user_id column. So I added:
class Foo extends Model
{
protected $fillable = [
'name',
'user_id'
];
public function setUserIdAttribute()
{
$this->attributes['user_id'] = Auth::user()->id;
}
}
And from my controller I'm calling for Foo::create($data) without user_id key.
But it doesn't work as expected. store() gives Integrity constraint violation because of user_id is missing. (User already logged in to achieve create page)
i cannot find official documentation about model-observers for Laravel 5.6. but you can still do it by this code
public static function boot()
{
parent::boot(); // TODO: Change the autogenerated stub
// it will automatically add authenticate user to created_by column of selected model
static::creating(function ($model){
$model->created_by = auth()->user()->id;
});
}
You provide an example where you used accessors.
https://laravel.com/docs/5.1/eloquent-mutators#accessors-and-mutators
From official doc:
The accessor will automatically be called by Eloquent when attempting to retrieve the value of first_name:
If you want to set default value for some attributes you need to use Observers.
<?php
// file app/models/Foo.php
namespace App\Models;
use App\Observers\FooObserver;
class Foo extends Model
{
protected $fillable = [
'name',
'user_id'
];
public static function boot() {
parent::boot();
parent::observe(new FooObserver);
}
}
<?php
// file app/observers/FooObserver.php
namespace App\Observers;
use App\Models\Foo;
class FooObserver {
public function creating(Foo $model) {
$this->user_id = Auth::user()->id;
}
}
About model observers in official doc:
https://laravel.com/docs/5.0/eloquent#model-observers

Trouble getting attribute of relation in Laravel

I'm having a trouble with a relation in Laravel 5. the thing is that I have a table User and that user belongs to a Group for that, in the User model I have this:
public function group(){
return $this->belongsTo('App\models\Group');
}
The model Group have this attributes: name,unity,level, init_date. I also put there a default function to return a group as String, this is the code:
public function __toString(){
return $this->name.' Unity '.$this->unity;
}
So, the thing that in a view a have many users and for each of them I want to display the unity, name,date. When I call $user->group it returns me correctly the name and the unity in a String (because the _toString function) that means that he is really querying the group perfectly, but then, when I want to access a simple attribute as unity,date,or name with $user->group->name Laravel gives me this error:
Trying to get property of non-object
I even tried $user->group()->name then I gets: Undefined property: Illuminate\Database\Eloquent\Relations\BelongsTo::$name
Edited:
The model User:
class User extends Model implements AuthenticatableContract, CanResetPasswordContract {
use Authenticatable, CanResetPassword;
protected $table = 'users';
protected $fillable = ['email', 'password','estate','filial_id','perfil_id','rol','cat_teacher'];
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = ['password', 'remember_token'];
public function __toString(){
return $this->email;
}
public function filial(){
return $this->belongsTo('App\models\Filial');
}
public function perfil(){
return $this->belongsTo('App\models\Perfil','perfil_id');
}
public function grupo(){
return $this->belongsTo('App\models\Group','group_id','id');
}
}
The model Group:
class Group extends Model {
protected $table = 'groups';
protected $fillable = ['name','unity','date'];
public function filiales() {
return $this->belongsTo('App\models\Filial');
}
public function teacher(){
return $this->belongsTo('App\models\User','teacher_id');
}
public function users() {
return $this->hasMany('App\models\User');
}
}
Then, in the controller I made a dd($users) and there not appear the relations, appears other relations but not this one. In the view I want to print some of the attributes in a table, for that I have:
<td>{{$user->group}}</td>
<td>{{$user->group->unity}}</td>
The first line works perfectly, and I donĀ“t know why.
The reason you're unable to return your group's name is that ->group() returns an instance of the query builder, and not an eloquent collection/object. Since a user belongs to a single group, modify your code in one of these two ways:
public function group(){
return $this->belongsTo('App\models\Group')->first();
}
And then access the group using one of the following methods:
$user = User::with("group")->where("id", "=", 1)->first();
$group = $user->group;
echo $group->name;
// OR
$user = User::where("id", "=", 1)->first();
$group = $user->group();
echo $group->name;
Or, leave the group() function as it is and access ->group()->first() on your $user object:
$user = User::where("id", "=", 1)->first();
$group = $user->group()->first();
echo $group->name;
Any of the above methods should properly return your group object's name (or other attributes). Check the Eloquent Documentation for detailed explanations on how to access these objects.

Resources