I have two objects out of my User model in Laravel. Let's say
public function someFunction(User $user) {
$adminUser = User::where('role', '=', 1);
if($adminUser === $user) {
return true;
}
return false;
}
Is this the proper way to compare two objects in Laravel? As per PHP Object Comparison, this should work.
Thanks for any input.
Since $user is a User instance, you can do this without executing any additional queries:
public function someFunction(User $user) {
return $user->role === 1;
}
This code will return true if user's role is 1 and false if role is not 1.
You should try this :
public function someFunction(User $user) {
if($user->role === 1) {
return true;
}
return false;
}
hope this work for you !!!
Related
When I want users not to be able to enter an individual resource I can use policies to do the following:
public function view(User $user, Model $object)
{
if($user->groupName != $object->groupName) {
return false;
} else {
return true;
}
}
This has as a result that the Components of your group have the eye icon (see red cirle). Components I do not want the user to see dont have the eye icon.
My desired result is that the should not be seen component is not shown at all. How can I achieve this?
I tried:
public function viewAny(User $user)
{
// $object does not exist here so I cannot use it to filter
if($user->groupName == $object->groupName) {
return true;
} else {
return false;
}
}
You need to update the index query of your resource. see more
public static function indexQuery(NovaRequest $request, $query)
{
return $query->where('groupName', $request->user()->group_name);
}
You should consider updating the relateble query too.
I have a function in my User model which is called isAdmin, if "Admin" is set to 1 in the database, it returns true, if not it returns false.
How is this gonna work with Auth::user()?
When I do Auth::user()->isAdmin(), it returns "Property [admin] does not exist on this collection instance."
Thats why I came to the conclusion it may not use the User model?
User model
public function isAdmin() {
if($this->admin == 1) {
return true;
} else {
return false;
}
}
public function view ()
{
if(Auth::check() && Auth::user()->isAdmin()) {
$user = User::all();
$post = Post::all();
$visit = Visits::all();
return view('admin')->with('post', $post)->with('user', $user)->with('visit', $visit);
} else {
return redirect()->to('/');
}
}
If I may suggest, for this use case, you can actually make do without an extra function. You could just say auth()->user()->admin, specially if the 'admin' column in the database is boolean type.
Otherwise (even admin coloumn is not boolean type) you can set up a mutator method in the model, like so:
public function getIsAdminAttribute()
{
return (bool) $this->admin;
}
Then to check you can access it like so: Auth::user()->isAdmin or auth()->user()->isAdmin
And better yet, you might want to read about Gate and Policies to achieve more robust access controlling. https://laravel.com/docs/5.7/authorization
Suggestion, change the code to just this:
public function isAdmin() {
return $this->admin;
}
This code does exactly the same as you've got above..
Now in your admin.blade.php you are using:
$user->isAdmin();
But in the controller you have:
$user = User::all();
which returns collection.
You should iterate over it, and check on each user instance if it is an admin:
$users = User::all();
In the view:
#foreach($users as $user)
#if($user->isAdmin())
{{ $user->name }} // some code here..
#endif
#endforeach
No Need To do anything just check if login then auth()->check() is return true then auth()->user() return the user
public function view ()
{
if(auth()->check() && auth()->user()->isAdmin()) {
$user = User::all();
$post = Post::all();
$visit = Visits::all();
return view('admin')->with('post', $post)->with('user', $user)->with('visit', $visit);
} else {
return redirect()->to('/');
}
}
public function isAdmin()
{
return $this->admin;
}
I need help with querying the result of relation between models. Two models are defined, User and Role model.
User:
public function roles()
{
return $this->belongsToMany('App\Role', 'role_users');
}
public function hasAccess(array $permissions) : bool
{
foreach ($this->roles as $role) {
if ($role->hasAccess($permissions)) {
return true;
}
}
return false;
}
public function inRole(string $slug)
{
return $this->roles()->where('slug', $slug)->count() == 1;
}
Role:
public function users()
{
return $this->hasMany('App\User', 'role_users');
}
public function hasAccess(array $permissions) : bool
{
foreach ($permissions as $permission) {
if ($this->hasPermission($permission)) {
return true;
}
}
return false;
}
private function hasPermission(string $permission) : bool
{
return $this->permissions[$permission] ?? false;
}
Also, a pivot table called role_users is defined. In the roles database several roles are pre-defined by seeding (Admin, Editor, Author).
I want to query the users by its roles, for example,
$editors = App\User::roles(2)->orderBy('name', 'asc')->get()
where in roles database the id of editor is 2. I got the error
PHP Deprecated: Non-static method App/User::roles()
How to solve this? Note: I'm using Laravel 5.6 and new to Laravel and framework. I tried to refer to docs but it confused me.
Thanks in advance.
You have to use whereHas(..):
$editors = \App\User::whereHas('roles', function ($q) {
$q->where('id', 2);
})->orderBy('name', 'asc')->get()
#devk is correct but here you have another way to get the data of user by role.
\App\Role::where('id', 2)->with('users')->get();
I Have this 3 tables like below :
Tools
Parts
Part_details
it is my the table structure :
Tool -> has many -> parts. part -> has many->part_details.
Tool : id*, name; Parts : id*, name, tool_id; part_details: id, part_id, total;
Question :
Using laravel Model, how can I get Tool with One part that has biggest total on parts_details ??
// Tool Model
public function parts(){
return $this->hasMany(Part::class);
}
// Part Model
public function part(){
return $this->belongsTo(Tool::class);
}
public function part_details(){
return $this->hasMany(PartDetail::class);
}
// PartDetail Model
public function part(){
return $this->belongsTo(Part::class);
}
Now query the Tool model
$tools = Tool::with('parts')->withCount('parts.part_details')->get();
$toolWithMaxCount = $tools->filter(function($tool) use ($tools){
return $tool->parts->max('par_details_count') === $tools->max('parts.part_details_count');
})->first();
You can improve this with adding some raw bindings to optimise it. I think you got the idea.
Tool model
public function parts() {
return $this->hasMany('App\Part');
}
Part Model
public function details() {
return $this->hasMany('App\PartDetail');
}
public function tool() {
return $this->belongsToMany('App\Tool');
}
Detail Model
public function part() {
return $this->belongsToMany('App\Part');
}
Controller
$tools = Tool::with('parts', 'parts.details')
->find($id)
->max('parts.part_details');
Use the the hasManyThrough Relationship to get the all part details related to tool and then you can check the one by one record and get the highest total of the tool part.
// Tool Model
public function partsdetails()
{
return $this->hasManyThrough('App\PartDetail', 'App\Part','tool_id','part_id');
}
In Your controller
$data = Tool::all();
$array = [];
if(isset($data) && !empty($data)) {
foreach ($data as $key => $value) {
$array[$value->id] = Tool::find($value->id)->partsdetails()->sum('total');
}
}
if(is_array($array) && !empty($array)) {
$maxs = array_keys($array, max($array));
print_r($maxs);
}
else{
echo "No Data Available";
}
I'm trying to build an alternative relationship that returns all records instead of only related records. I have tried returning a query builder, but that doesn't work, it must be a relationship. What should I return to make this work?
public function devices()
{
if ($this->admin) {
// return all devices relationship instead
} else {
return $this->belongsToMany('Device', 'permissions');
}
}
Fiddle: https://implode.io/XXLGG8
Edit: I'd like to continue building the query in most cases, not just get the devices.
The devices() function in your model is expected to return a relation, you shouldn't add the if statement there. Make your devices() function like this:
public function devices()
{
return $this->belongsToMany('Device', 'permissions');
}
In your User model add a new function:
public function getDevices() {
if($this->admin === true) {
return Device::all();
}
return $this->devices();
}
Now you can do:
$admin->getDevices(); // will return all devices
$user->getDevices(); // will return only relations
I actually went a slightly different way and used a scope:
protected function scopeHasAccess($query, User $user)
{
if ($user->admin) {
return $query;
}
return $query->join('permissions', 'permissions.device_id', "devices.id")
->where('permissions.user_id', $user->user_id);
}
Add devices accessor method to the User model and implement your logic there.
public function getDevicesAttribute() {
if ($this->admin) {
return Device::all();
}
return $this->getRelationValue('devices');
}
See updated "fiddle".