Laravel 4 #foreach - laravel-4

Using a resourceful UsersController and $users.
It seems that when $users has only 1 entry, the #foreach loop doesn't work?
In UsersController:
public function show($id) {
$users = User::find($id);
return View::make('users')->with('users',$users);
}
If I just use "return $users", the value of $users is:
{"id":"1","username":"user1"}
In users.blade.php:
#foreach($users as $user)
{{$user->username}}
#endforeach
When there are 2 or more users it worked, but with URI app.com/users/1, it only returns one (see above) and the new error is:
"Trying to get property of non-object"
Why is this an error in users.blade.php?

It's more a question of what User::find($id) is returning..
Query builder methods return an instance of the Collection class, which represents a collection of Models. For instance, here we get back a Collection containing one Model.
$users = User::where('id', '=', $id)->get();
However the find() method returns a single Model
$users = User::find($id);
A single Model isn't iterable in the same way as a Collection, which returns a Model with each iteration, hence the error you're seeing!

Related

Laravel 6: trying to get property of non-object

Error: Trying to get property 'gender_id' of non-object
Controller:
public function printreports(Request $request)
{
$id = $request->get('select2'); //eg. id=1
$teachers = DB::table('teachers')->find($id);
return view('teachers.report1',compact('teachers'));
}
View:
#foreach($teachers as $teacher)
{{$teacher->gender_id}}
#endforeach
while if i do it with Eloquent by replacing following query it works, but i want to do it with DB query as stated above.
$teachers = Teacher::find($id);
you need use where, and after it you will have collection.
$teachers = DB::table('teachers')->where('id', $id)->get();
when you use find, you have single item
You don't need to use foreach while you use find().
#if(sizeof($teachers))
{{$teachers->gender_id}}
{{$teachers->gender_id}}//whatever field you need to display
{{$teachers->gender_id}}//whatever field you need to display
#endif
If you use get(),
$teachers = DB::table('teachers')->where('id','=',$id)->get();
#if(sizeof($teachers))
#foreach($teachers as $teacher)
{{$teacher->gender_id}}
{{$teacher->gender_id}}//whatever field you need to display
{{$teacher->gender_id}}//whatever field you need to display
#endforeach
#endif
$teachers = DB::table('teachers')->find($id); will return a single Model or  null, try using $teachers = DB::table('teachers')->get();
If you want to return collection to view then use get() method like this:-
public function printreports(Request $request)
{
$id = $request->get('select2');
$teachers = DB::table('teachers')->where('id', $id)->get();
return view('teachers.report1',compact('teachers'));
}

How to call a function after getting model from database?

i'm getting model using this code:
$user = \App\Http\Models\User::where('id', $id)->with('services')->get();
and i want to call this function for example
$user->getServiceList(); //this metod gets ALL services, not hasMany
but it causes an error
Method getServiceList does not exist
get() loads a collection, so you need to iterate over it to get objects:
$users = \App\Http\Models\User::where('id', $id)->with('services')->get();
foreach ($users as $user) {
echo $user->getServiceList();
}
It's much better to use find method if you are searching by user id:
$user = \App\Http\Models\User::with('Service')->find($id);
$user->getServiceList();

Laravel conditional on relation: return first()

I have a Laravel 5.2 one-to-many relation and I want to return the model and put a condition to relation.
I've tried this:
$categories = Category::with(['descriptions' => function($d) use ($default_language) {
$d->where('language_id', $default_language->id);
}])->get();
It work fine, I just want something else: the relation should not be a collection or array, just a simple object. I want to do something like
$d->where('language_id', $default_language->id)->first();
, just in this case first() is not working. Any ideas?
EDIT
Actually first() is not working properly, it returns first description just for the first object returned, for others it return nothing.
Try this:
$categories = \Jobinja\CMS\Blog\Models\Category::with([
'descriptions' => function ($q) use ($defaultLanguage) {
return $q->where('language_id', $defaultLanguage->id)->take(1);
}
])
->get()
->map(function ($item) {
if ($item->descriptions->isEmpty() === false) {
$item->description = $item->descriptions->first();
}
return $item;
});
and get to description:
foreach ($categories as $category) {
$description = $category->description;
}
You can't do that but you can use first() on a collection later, for example in a view:
#foreach ($categories as $category)
{{ $category->descriptions->first()->name }}
#endforeach
I can say to use instead of first() find() and give it the language_id or $default_language->id and this will try to find in the table first the column id and assign the value. If you have different id column name give it to the find like find(['your_column_name' => '<your_value']).
If you want array to something like ->toArray(). You can test different scenarios in tinker. php artisan tinker
Here is a link to document this -> https://laravel.com/docs/5.3/eloquent#retrieving-single-models

Laravel 5.2 How to get all user which contains permission Many to Many

I have table with many to many relationship.
User many to many Permission
I already define many to many relationship on both model, and create the pivot table also.
What I want is get all user which contain permission name
What I have done so far is
User::all()->permissions->contains('name', 'access.backend.admin')->get();
But it give me
Undefined property: Illuminate\Database\Eloquent\Collection::$permissions on line 1
What wrong with my code?
User::All() returns a collection not model object. You have iterate over the collection to get the model object and use ->permissions().
For exapmle:
$users = User::all();
foreach ($users as $user) {
$user->permissions->contains('name', 'access.backend.admin'); // returns boolean
}
Or you can get a single model from DB as:
$user = User::first();
$user->permissions->contains('name', 'access.backend.admin'); // returns boolean
Update 1
To get users which contain desired permission use filter() method as:
$filtered_users = $users->filter(function ($user) {
if ($user->permissions->contains('name', 'access.backend.admin')) {
return $user;
}
});
Update 2
You can also write a query which returns the desired result as:
$filtered_users = User::whereHas('permissions', function($q) {
$q->where('name', 'access.backend.admin');
})->get()
I have a similar case of questions and tags, they have many to many relationship.
So when i have to fetch all question with a particular tag then i do this
$tag = Tag::where('name','laravel')->get()->first();
I first retrieved the Tag model with name laravel.
and then retrieved all questions having tag laravel.
$questions = $tag->questions;
Similarly you can do this
$permission = Permission::where('name','access.backend.admin')->get()->first();
$users = $permission->users;

Laravel - Trying to get property of non-object in chained view

Having a small problem with retrieving a new object on my view. I keep getting the error 'Trying to get property of non-object'.
The field I am trying to display 'oil_gas_skillsgap' is a valid field and when I do a simple return it spits out...
[{"oil_gas_job_id":"4","industry_job_id":"43","oil_gas_skillsgap":"test text here"}]
CONTROLLER
public function showjob($slug)
{
$job = OilGasJob::where("slug", "=", $slug)->first();
if (is_null($job))
{
return Redirect::to('/');
} else {
$jobId = $job->id;
$roleId = Session::get('industryrole');
$skills = DB::table('industry_job_oil_gas_job')
->where('oil_gas_job_id', '=', $jobId)
->where('industry_job_id', '=', $roleId)
->get();
return View::make('job')
->with('job', $job)
->with('skills', $skills);
}
}
VIEW
{{ $job->job_title}}
{{ $skills->oil_gas_skillsgap }}
$skills is probably an array, not an object, even if the query has only one result.
If you know for a fact that your query will return one result, use first() and you'll get it as an object directly.
$skills = DB::table('industry_job_oil_gas_job')
->where('oil_gas_job_id', '=', $jobId)
->where('industry_job_id', '=', $roleId)
->first();
Otherwise, remember the following: when using the DB class for queries, Laravel will always return an array. If you use an Eloquent model, it will return an Illuminate\Support\Collection object. In both cases that is true even if no row is found (the array or Collection will be empty). The first() method, on the other hand, will either return an object (stdClass when using DB, or a model when using Eloquent) or null.
#user3189734,
job_title is not a part of $job collection, that is why it is throwing 'Trying to get property of non-object'.

Resources