Laravel - oneToMany returning Undefined property - laravel

I just searched for this problem in all posts but i cant get the answer.
I have 3 tables: users | categorys | sectors with the below model:
User.php
public function categorys(){
return $this->hasMany('Category');
}
Category.php
public function user(){
return $this->belongsTo('User');
}
public function sectors(){
return $this->hasMany('Sector');
}
Sector.php
public function category(){
return $this->belongsTo('Category');
}
Tables
users:
id,name
categorys:
id,name,user_id(fk)
sectors:
id,name,category_id(fk)
I want to print in a view all the sectors from authenticated user, with something like this:
$user = new User;
$user = Auth::user();
$sectors = $user->categorys->sectors;
and use this in $sectors variable in view
#foreach($sectors as $sector)
{{ $sector->id }}
{{ $sector->name }}
#endforeach
But i get this error:
Undefined property: Illuminate\Database\Eloquent\Collection::$sectors
Need help! Thanks
BR

Either you forgot to mention it in your article, or the sector_id field is missing in the categorys table.
According to your database structure there is no foreign key from table categorys to table sectors

As i mentioned before here is the answer for the above issue.
The hasmanythought relation is the correct way to relate and easy query thouse 3 tables.
For model User.php you need to create the relationship:
public function sectors(){
return $this->hasManyThrough('Sector','Category');
}
Now in your controller you need to do:
$user = new User;
$user = Auth::user();
$sectors = $user->sectors;
#return the view showsectors
return View::make('showsectors')->with('sectors', $sectors);
Use this variable (sectors) to print the query result (all sector's descriptions from one user) in your view, with something like the below:
#foreach($sectors as $sector)
{{ $sector->id }}
{{ $sector->description }}
#endforeach
Thanks for helping with this.
BR

Related

How to retrieve user name from user table by using data (user_id) from another table having relationship

I have two models
User.php
public function opportunities()
{
return $this->hasMany('App\Opportunity');
}
Opportunity.php
public function user()
{
return $this->belongsTo('App\User');
}
I have user_id column in opportunities table and inserted user id (from user table using Auth) every time user posts record.
Now i need a view to return "this post is posted this user".
First I find the post id by
$posts = Opportunity::find($id);
$posted_by = User::find($posts->user_id);
return view('opportunity.detail')->with('post', $posts, 'posted_by', $posted_by);
I have rendered user name by {{$posted_by->name}}
But I got undefined constant in the view file $posted_by while $post is fine. Am I doing it in right way or not? I am passing two array variable to the post and its not working. Any help will be appreciated.
Your controller could look like:
return view('opportunity.detail', [
'post' => Opportunity::find($id);
]);
In the view to show user name:
Post {{ $post->title }} posted by {{ $post->user->name }}
https://laravel.com/docs/5.5/eloquent-relationships#relationship-methods-vs-dynamic-properties
If for some reason you want to use ->with(), do this:
->with(['post' => $posts, 'posted_by' => $posted_by]);
Or:
->with('post', $posts)->with('posted_by', $posted_by);
You can put this
public function getUserName() {
return User::where('id', $this->user_id)->first()->name;
}
in your Opportunity.php model and call it in you view
#foreach ($posts as $post)
{{ $post->getUserName() }}
#endforeach

Laravel 5.5 Relationships - ErrorException Trying to get property of non-object

Can't display an info from DB to view, have an error
ErrorException
Trying to get property of non-object
Let me explain the logic:
User can create many companies
Companies can have many items
I don't have problems with inserting info to DB, everything is fine.
I can display every info from Users table and Company table in my Show View, but I can't display info from Company_Items tables in my view.
I guess something is wrong with my Relationships or keys, but what?
Trying to display Item name that belong to the specific company
{{$company->company_items->name}}
Company Table:
id(int)
company_name(string)
info(text)
user_id(int)
Company_items Table:
id(int)
company_id(int)
name(string)
Company Model:
class Company extends Model
{
protected $table = 'company';
//relation. MANY companies can be created by ONE user
public function user(){
return $this->belongsTo('App\User');
}
//relation. ONE company can have MANY items
public function item(){
return $this->hasMany('App\Item');
}
}
Item Model:
class Item extends Model
{
protected $table = 'company_items';
//relation. MANY items can be applied TO ONE company
public function company(){
return $this->belongsTo('App\Company');
}
}
Controller:
public function show($id)
{
$company = Company::find($id);
$user = User::find($id);
$company_items = Item::find($id);
return view('company_show')->with(['company' => $company,'company_items' => $company_items]);
}
View:
This is <b>{{$company->company_id}}</b> page info created by <b>{{$company->user->name}}</b><br>
Company category is <b>{{$company->company_category}}</b>.<br>
Item name is <b>{{$company->company_items->name}}</b>. // Can't display this expression
$company->company_items is a list of all the items of the company, you can't call a param on it. And you declared your relation with the name item and not company_items
Try to do :
$company->item[0]->name
or
#foreach($company->item as $item)
{{ $item->name }}
#endforeach
First error you made is:
$company_items = Item::find($id);
This will return the company Item that has the ID=$id which means it will return the Item that has the same ID as the company! I'm sure that's not what you want.
Instead you can do:
$company_items = $company->item;
which will return all the items of that company
and in your view you can access the items with a foreach loop:
#foreach($company_items as $item){
{{$item->name}}
}

Laravel 5.3 access hasone in elequant from view

I'm trying to access a relations table from a collection of data passed in from the controller. I am able to iterate the collection in my view but I am unable to access the relationship data.
There are 2 tables:
stocks (default model)
stock_datas (has a foreign key stock_id which is already setup)
Controller:
public function getstock() {
return view('vehicles.getstock', ['stock' => \App\Stock::all()]);
}
Model (App\Stock) and then (App\StockData)
// From stock model:
public function stockdata() {
return $this->hasOne('App\StockData');
}
// Stock Data model:
public function stock() {
return $this->belongsTo('App\Stock');
}
View (loop):
#foreach ($stock as $k => $v)
{{ print_r($v->stockdata()->get())->year }}
#endforeach
When I try the query below, I get a
Undefined property: Illuminate\Database\Eloquent\Collection::$year (View: F:\websites\tempsite\resources\views\vehicles\getstock.blade.php)
However, year is a column in the stock_datas table.
I am also able to print_r data from the \App\StockData() table so the reference to the table is correct as doing print_r(\App\StockData::all()) from the controller does return all the rows as expected.
What am I doing wrong?
Since it's one to one relation, you should do it like this:
#foreach ($stock as $v)
{{ $v->stockdata->year }}
#endforeach
First one You have to change {{ print_r($v->stockdata()->get())->year }} this line, remove print_r. Next one in foreach loop you can do something like this
#foreach($stock as $one)
{{ $one->stockadata()->first()->year }}
#endforeach
For better solution you should check if isset $one->stockadata()->first()
and after that call ->year. Finally code should be like this
#foreach($stock as $one)
{{ isset($one->stockadata()->first()) : $one->stockadata()->first()->year : 'Default' }}
#endforeach
When calling get() method on any relationship You will always receive collection, no matter what relationship You have.
There are at least two (2) ways to solve Your problem:
1. $v->stockdata->year
2. $v->stockdata()->first()->year
I would suggest You to use first one, because Your stockdata has 1:1 relationship.
Good luck!
For example:
Stock.php model
class Stock extends Model
{
protected $primaryKey = 'id';
function stockdata() {
return $this->hasOne('App\StockDatas', 'id', 'stock_id');
}
public function getStock(){
return Stock::with('stockdata')->get();
}
}
In contriller
public function getstock(Stock $stock) {
return view('vehicles.getstock', ['stock' => $stock->getStock]);
}
view
#foreach ($stock as $k => $v)
{{ $v->stockdata->year }}
#endforeach

Laravel access relation

I want to access a relation of the model when I get all the results but I keep getting the following error:
Undefined property: Illuminate\Database\Eloquent\Collection::$voornaam
Code:
- Model : Selectie.php
public function User()
{
return $this->hasMany('User', 'id', 'user_id');
}
- Controller
$selectie = Selectie::where('wedstrijd_id', '=', $id)->get();
return View::make('base.match.show')->with('selectie', $selectie);
- View
#foreach($selectie as $sel)
{{ $sel->user->voornaam }}
#endforeach
You have One to Many Relation in Selectie model. That means , $sel->user returns Collection Array , you cant reach array attributes like that.
#foreach($selectie as $sel)
#foreach($sel->user as $user)
{{ $user->voornaam }}
#endforeach
#endforeach
Try like this , otherwise you have to change your Selectie Model - User Model Relation type with One-To-One

Laravel - Eloquent Joins

I'm just starting to learn laravel and its orm system, Eloquent. I'm not sure how to correctly join tables with it though. I have 3 models: User, Account, AccountType and I don't know how to join Account with Accounttype.
Account Model Class:
public function accounttype(){
return $this->hasOne('AccountType');
}
This is to pass accounts information to view:
$accounts = User::find(Auth::user()->id)->accounts;
$accounts->load('accounttype');
return View::make('accounts.accounts')->with('accounts', $accounts);
That will give the following error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'accounttypes.account_id' in 'where clause' (SQL: select * from accounttypes where accounttypes.account_id in (1, 2, 3))
It should be pulling by id in the accounttypes table not account_id. I can list the user accounts just fine, I just don't know how to join the accounttypes table to the account table.
Database Tables:
Users
id
username
password
timestamps(updated_at / created_at)
Accounts
id
name
user_id
accounttype_id
timestamps
AccountTypes
id
name
Each user can have more than one account and each account will have an account type.
In User model:
public function accounts()
{
return $this->hasMany('Account');
}
In Account model:
public function user()
{
return $this->belongsTo('User');
}
public function accountType()
{
return $this->belongsTo('AccountType', 'accounttype_id', 'id');
}
In AccountType model:
public function accounts()
{
return $this->hasMany('Account', 'accounttype_id', 'id');
}
Then in your Controller:
// This will return a user with all accounts ($user->accounts will be collection)
$user = User::with('accounts')->find(Auth::user()->id);
Or:
$user = User::with('accounts.accountType')->find(Auth::user()->id);
// You may pass the $user as well and then loop the $user->accounts in view
return View::make('accounts.accounts')->with('accounts', $user->accounts);
In your view you may loop to get all accounts like:
#foreach($accounts as $account)
{{ $account->name }}
{{ $account->accountType->name }}
#endforeach
Since $user->accounts is a collection so you may either run a loop or specifically get an account using something like this:
{{ $accounts->first()->name }}; // Get first one's name
{{ $accounts->get(0)->name }}; // Get first one's name
{{ $accounts->get(1)->name }}; // Get second one's name
{{ $accounts->last()->name }}; // Get last one's name
if you pass the $user instead of $accounts like this:
return View::make('accounts.accounts')->with('user', $user);
Then change the loop as well, like this:
#foreach($user->accounts as $account)
{{ $account->name }}
{{ $account->accountType->name }}
#endforeach
You can make sure if that user has accounts in the view before you start the loop, like:
#if($user->accounts->count())
// Loop Here
#endif

Resources