How to get All data from a model except one? - php

I want to retrieve all users data except one.for that i used the following query
$users=User::whereNotIn('name',['admin'])->pluck('id','name');
When i dd() the output I see all the users data except the one But when I send the query results in foreach() loop in view page I see
Trying to get property of non-object
Error in view page.What's the Error here? Can anyone suggest me please?
Here is the foreach loop i used in view page
#foreach($users as $user)
<option value="{{$user->id}}">{{$user->name}}</option>
#endforeach

$users = User::where('id', '!=', Auth::id())->get();
this one except current login user..you can set admin id...in such field..
or you can use this also..
$users = User::all()->except(Auth::id());
both are work!!

pluck() creates an array with [id => name] structure, so change the code in assign_rol‌​e.blade.php to:
#foreach ($users as $id => $name)
<option value="{{ $id }}">{{ $name }}</option>
#endforeach
And pluck() parameters to:
->pluck('name', 'id');

it may be a bit late to answer on that question but since it helped me NOT REPEATING MYSELF i'll share it with ya!
using the exception everywhere in your application will lead to a big mess in your code, so whenever you want to dig into your users you'll need to except yourself... imagine you wanted to except the user X or Y too later?
it's kind of unnecessary repetition.
User::all()->except(Auth::id())
Instead, you can just override the all method and set a global exception.
add this following to your User Model:
/**
* get all users except specified ones
*
* #param array|mixed $keys
* #return array
*/
public static function all($keys = null)
{
$data = parent::all(); # grep data from parent
return $data->except(auth()->id); # except whoever you wanted
}
and you can use your all as you used to do wherever you wanted!
User::all(); // this will exclude you

Related

Laravel - Eager Loading

I'm trying to understand Eager Loading using Laravel to avoid generating a lot of unnecessary queries. I want to get 15 last added Posts and also get their rates from relationship of my rates table (before I was getting Posts and later in foreach I was calling for $item->avgRate() that creates 15 additional queries :S).
My Post model:
public function rates()
{
return $this->hasMany(Rate::class);
}
public function scopeLastAdded($query, $limit = 15)
{
return $query->latest()->limit($limit)->with('rates')->get();
}
This works, for each post, I'm also getting all rates, but the main goal is to make some function to calculate avg rate for each post and not retrieve all rates. I created a new method:
public function avgRate()
{
return number_format($this->rates()->avg('rate'), 1, '.', '');
}
When I use with('avgRate') my model fails:
Call to a member function addEagerConstraints() on string
How can I get avgRate in some clean way with my last 15 Posts to perform only 2 queries and not 16?
Expected output:
// Post view
#foreach ($posts as $post)
<div>{{ $post->title }}</div>
<div>{{ $post->avgRate }}</div> //I want to get data without performing 15 queries
#endforeach
I would use a subquery to achieve this. Also, to make things a little bit cleaner, you can create a scope for fetching the rating:
public function scopeWithRating($query)
{
$rating = Rate::selectRaw('AVG(rate)')
->whereColumn('post_id', 'posts.id')
->getQuery();
$query->select('posts.*')
->selectSub($rating, 'rating');
}
... and to use it, you'd do:
Post::withRating()->get();
Now, your Post objects will also contain a column rating, and that has been done with, essentially, a single query.
Here's an example to illustrate this.

Build database query in Laravel with eloquent or DB

I need your help to build a query in Laravel either eloquent or DB query would do too.
My table name is Users
To see the DB structure, open the following link:
https://jsfiddle.net/vardaam/mvqzpb2j/
Every user row has 2 columns referral_code and referred_by_code which means every user can refer to someone and earn bonus similarly the same user was also been referred by some one.
I would like to return the information on page with loop in users details along with Username of the user who had referred him to this. To track the same I created those 2 columns in the same table i.e.: referral_code and referred_by_code.
I do not know how to write this in 1 query or how to combine 2 queries and get the desired results.
My controller code looks like below:
$obj_users = User::get();
$codes = [];
$referrers = [];
foreach( $obj_users as $referred_by_code )
{
//Following fetches all user's referred_by_code's code
$codes[] = $referred_by_code->referred_by_code;
}
foreach ($codes as $code)
{
//Following fetches usernames of the given referred_by_code's codes
$referrers[] = User::where('referral_code', $code)->first()->username;
}
return view('users.users', compact(['users', 'paginate', 'referrers']));
The returning $users variable provides me loop of users data but I do not know how to attach those referrer's username to that object.
I tried my level best to describe, please ask incase what I said doesn't make sense, will be happy to provide further clarification.
Best
You can add into your User model the following relationship:
public function referredBy()
{
return $this->belongsTo(User::class, 'referred_code', 'referral_code');
}
In your controller you can use:
$users = User::with('referredBy')->get();
return view('users.users', compact('users'));
and later in your view you can use:
#foreach ($users as $user)
{{ $user->username }} referred by {{ $user->referredBy ? $user->referredBy->username : '-' }}
#endforeach

ErrorException Missing required parameters laravel

I am having an issue by modifying the route for a view. I want instead of /company/id to show /company/id/name
the route:
Route::get('/company/{id}/{name}', 'PagesController#showCompany')->name('company.detail');
show method in controller:
public function showCompany($id){
$company = Company::find($id);
return view('company.show')->with('company', $company);
}
and in the view $companies is from a search controller - and it should get the results with a link to open the view
#foreach($companies as $company)
Show detail
#endforeach
if using only with id like /company/id works. What i am wrong?
A simple an elegant way (i think) is:
{{route('company.detail', ['id' => $company->id, 'name' => strtolower(preg_replace('/[^A-Za-z0-9-]+/', '-', $company->company_name))}}
You can have a friendly url name. I am sure that there are better solutions out there.
If you have more params in the route you can use an associative array and initialize each param name with a value.
the controller now is the same with the id.

Retrieving relation of users and usermeta table from wordpress database using Eloquent

I am trying to access a user's first_name in my custom script which uses Eloquent to retrieve data (in Laravel 5 actually )
So,
Here is how i defined relationship (one to many ) // is that correct ?? Wp Guru may tell
In User Model, i have
public function usermeta() {
return $this->hasMany('App\Usermeta','user_id');
}
In my UserController I have
$users = \App\User::with('usermeta')->get();
And here how i access it in my views
#foreach ($users as $user)
<tr>
<th>{{$user->ID}}</th>
<th>{{$user->usermeta->/*how to access particular meta key here*/}}</th>
<th>{{$user->display_name}}</th>
</tr>
#endforeach
So the problem is, everything works except when i try to access the usermeta relation, I'm actually not sure how to query a particular meta key's value by passing meta_key as an argument either in my relation or in foreach loop
I tried directly accessing like $user->usermeta->first_name but that is incorrect for sure.
How can i retrive the meta_value from a usermata table in wordpress database using Eloquent Model?
Edit 1
trying the accessor method approach by #james-flight
https://stackoverflow.com/a/30871346/1679510
It works when i know the position of the record in collection object.
if ($usermeta->count() > 0) {
return $usermeta[0]->meta_value;
}
However, since the meta_key can be anything, and may reside at other position.
if the meta_key is first_name , then $usermeta[1] have the array of column values for it, and so on.
if ($usermeta->count() > 0) {
return $usermeta[/*This cannot be hard code */]->meta_value;
}
How to get it resolved
Usermeta is a hasMany relationship, which means Eloquent will return a Collection object containing multiple Usermeta models.
You could instead do this:
{{ $user->usermeta[0]->first_name }}
Or this:
#foreach($user->usermeta as $usermeta)
{{ $usermeta->first_name }}
#endforeach
Edit
To use meta_key and meta_value as a key value pair, you could write an accessor method on User:
public function getMetaValue($key) {
$usermeta = $this->usermeta->filter(function ($usermeta) use ($key) {
return $usermeta->meta_key === $key;
});
if ($usermeta->count() > 0) {
return $usermeta[0]->meta_value;
}
}
And then access in blade like so:
{{ $user->getMetaValue('first_name') }}
This will get slow at high volume though.
Edit 2
The above method should in fact be as follows, to ensure the array key exists:
public function getMetaValue($key) {
$usermeta = $this->usermeta->filter(function ($usermeta) use ($key) {
return $usermeta->meta_key === $key;
});
if ($usermeta->count() > 0) {
return $usermeta->first()->meta_value;
}
}

Correct way to run a select query from blades in laravel 5 using eloquent

What is the Correct Way to retrieve a column value based on certain select filter on a Model variable availed by compact method inside the blade. (Larevl 5)
I read that Its a bad practice to query database staright from views, and hence i followed the convention to avail the required data with compact method to view
However, In a scenario where I need to query another table based on certain column value returned in foreach loop inside a blade from first table, I am unable to figure out correct Approach
Example: I have two Models User & Group
Schema User Table
id,name,email,group_id
Scheme Group Table
id,groupname
Here is the UserController -> compact method
$users = \App\User::all(array('id','name','email','group_id'));
$groups = \App\Group::all(array('id','group_name'));
return view('user.index', compact('users','groups'));
Here how the blade needs them
#foreach ($users as $user)
<tr>
<th>{{$user->id}}</th>
<th>{{$user->name}}</th>
<th>{{$user->email}}</th>
<th>
<!-- Here i need to run something like
select group_name from group where id = $user->id -->
{{$groups->where('id','=',$user->group_id) }}
</th>
<th>Actions</th>
</tr>
#endforeach
I know this returns an array , and I'have two questions here
How to get the value for group_name column from the Group Model based on group.id = $user->id in a foreach loop
Since Its a bad practice to query db from blade, how would I avail the values from a model by passing data via compact from controller to blade, when the where clause parameter's are not yet known.
Edit 1:
I modified the last group query as
<th>#if($groups->where('id','=',$user->group_id))
#foreach($groups as $group)
{{$group->group_name}}
#endforeach
#endif
</th>
And I was able to get the result, however this again isn't a correct approach , so question remain unanswered
In User model
public function group()
{
return $this->belongsTo('App\Group');
}
In Group model
public function users()
{
return $this->hasMany('App\User');
}
In your controller
$users = \App\User::with('group')->get();
return view('user.index', compact('users'));
Now in your view you can do
$user->group->name;
I appreciate the fact that you know "It's bad practice to query from view".
Why don't you use join.
DB::table('users')->join('groups', 'users.group_id', '=', 'groups.id')->get();
Then pass the result to your view and loop through it.
Here you will have each user data associated with his group data.

Categories