Laravel Get all related data from models - php

I have 2 many to many relationships and trying to get all related data.
User model:
public function roles()
{
return $this->belongsToMany('App\Role', 'user_role_pivot', 'user_id', 'role_id');
}
Role model:
public function rolepermissions()
{
return $this->belongsToMany('App\RolePermission', 'role_permissions_connect', 'role_id', 'role_perm_id');
}
I'm making policies and want to get all values from my rolepermissions.
my policy:
public function createrole(User $user)
{
foreach ($user->roles as $role) {
foreach ($role->rolepermissions as $permission) {
return $permission->permission_name;
}
}
}
It only returns only one result, but i want to get all related data from role permissions.

As soon as a function hits return, it stops to execute and returns the result. It's different than for example yield return in C# where you can actually return multiple values.
Anyways, You might want to add everything to an array and then use your array to execute actions, like this:
public function createrole(User $user) {
$array = [];
foreach ($user->roles as $role) {
foreach ($role->rolepermissions as $permission) {
array_push($array, $permission);
}
}
dd($array); //add this line if you want to see your array's items
foreach($item in $array){
//do something
}
}
Now that we're doing best practices anyways, you can also do this:
foreach ($user->roles as $role) {
foreach ($role->rolepermissions as $key => $permission) {
$array[$key] = $permission;
}
}
Which is performance-wise probably more efficient.

You're returning $permission->permission_name
so the return forces the function to stop executing. You're better off returning an array.
$roles = [];
foreach ($user->roles as $role) {
foreach ($role->rolepermissions as $permission) {
$roles[] = $permission->permission_name;
}
}
}
return $roles;

Related

No database entries when iterate array from database Laravel

protected function show()
{
$users = User::all();
$letters = Letter::with('user');
$userLetter = $letters->where(['user_id' => 2])->count();
//Here function work right. Shows that we have 10 users
foreach ($users as $user) {
$userLetter = $letters->where(['user_id' => $user->id])->first();
if($userLetter){
//Here it shows that only the first user exists, returns null for the rest users.
}
}
}
We get an error when we sort the array with foreach.
No record is found in the database except the first.
For other entries, return null.
outside foreach no errors.
Just move your object inside the loop like below.
protected function show()
{
$users = User::all();
$userLetter = $letters->where(['user_id' => 2])->count();
//Here function work right. Shows that we have 10 users
foreach ($users as $user) {
$userLetter = Letter::with('user')->where(['user_id' => $user->id])->first();
if($userLetter){
}
}
}
You would probably be better off using a letter relationship on the User.
On the User model you could do something like :
public function letter()
{
return $this->hasOne(Letter::class, 'user_id');
}
Then you could in the controller:
protected function show()
{
$users = User::with('letter')->get();
foreach ($users as $user) {
if ($user->letter) {
// do things
}
}
}

Laravel Eloquent relation between models

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();

Iterating through collection - laravel

I am developing an online ecommerce for the first time and currently, i am not able to iterate through my collection.
Every item for a shop is categorized into a product category. My relationship is below
Category
public function items()
{
return $this->belongsToMany('App\Item','category_item','category_id','item_id')
->withTimestamps();
}
Items
public function categories()
{
return $this->belongsToMany('App\Category','category_item','item_id','category_id')
->withTimestamps();
}
This code here is able to fetch the groups and their products. I try to loop through to get the names of the products like below but it only displays the name of the last product in the database.
Why is this happening?
ItemController
//get id of product categories and display all products in grid table
$items_in_table = Category::whereIn('id',$request->get('product_category'))->with('products')->get();
foreach($items_in_table as $item)
{
return $item->name;
}
update
$temp
foreach($items_in_table as $item)
{
temp = $item;
}
return $temp
response
{"id":2,"title":"freight","no_of_contacts":0,"user_id":1,"created_at":"2018-04-15 23:55:30","updated_at":"2018-04-15 23:55:30","items":[{"id":1,"name":"AirBag ","phone":"0247878234","group_id":null,"user_id":1,"created_at":"2018-04-16 00:14:20","updated_at":"2018-04-16 05:31:05","pivot":{"group_id":2,"customer_id":1,"created_at":"2018-04-16 05:33:08","updated_at":"2018-04-16 05:33:08"}}
enter image description here
let's define our relationships first
Category:
public function items()
{
return $this->belongsToMany('App\Item')
->withTimestamps();
}
Item:
public function categories()
{
return $this->belongsToMany('App\Category')
->withTimestamps();
}
then in your controller:
$items_in_table = Category::with('items')->get();
$names = [];
foreach($items_in_table as $category) {
foreach($category->items as $item) {
$names[] = $item->name;
}
}
dd($names);
Maybe you need to put it in an array and then rotate it
$items_in_table = Category::whereIn('id',$request->get('product_category'))->with('products')->get();
$name = [];
foreach($items_in_table as $item)
{
$name[] = $item->name;
}
return $name;
foreach will not manipulate the values of the array
Some possible solutions:
Use a reference, this will change the values in $items_in_table
foreach($items_in_table as &$item)
{
$item = $item->name;
}
Use map (since it is an Laravel-collection), this will also alter the array
$items_in_table->map(function ($item) {
return $item->name;
})
you can Access any relation like this way .
For View what is you are getting. you can also use dd($item->quoteReturnDetail)
return collect($models->items())->transform(function ($item, $index){
if( $item->quoteReturnDetail){ dd($item->quoteReturnDetail); } });

cakephp - triggered - after execution of query

How can change output one of model in all queries?
This means that queries run on this model, then go to a specific function.
for example, in user model, how remove password field for all queries
thanks
Add the following to your model:
public function afterFind($results, $primary = false){
foreach ($results as $key => $val) {
unset($results[$key][$this->alias]['password']);
}
return $results;
}
This should also work:
public function afterFind($results, $primary = false){
return Hash::remove($results, '{n}.'.$this->alias.'.password');
}

Passing an array in the construct of a controller with laravel

I am wanting to find out how I can pass in roles as an array because when I try to do this in my construct of my controller it always seems to only be Administrator.
The following is my app/controllers/UserscController.php
class UsersController extends BaseController {
public function __construct()
{
parent::__construct();
$this->beforeFilter('role:Administrator,Owner');
}
}
The following is my app/filters.php
Route::filter('role', function($route, $request, $roles)
{
if(Auth::guest() !== true)
{
if(!empty($roles))
{
$roles = explode(',', $roles);
if(count($roles) > 0)
{
foreach($roles as $role)
{
if (Auth::user()->role->role_name == $role)
{
return;
}
}
}
}
return Redirect::to('/youshallnotpass');
}
});
You can set the roles as a parameter in your controller. To load the roles into your filter you would do this:
Route::filter('role', function($route, $request)
{
if(Auth::guest() !== true)
{
$roles = $route->parameter('roles');
if(!empty($roles))
{
foreach($roles as $role)
{
if (Auth::user()->role->role_name == $role)
{
return;
}
}
}
return Redirect::to('/youshallnotpass');
}
});
Note:
Before laraval 4.1 you would use: $roles = $route->getParameter('roles'); instead of $roles = $route->parameter('roles');
Hope this helps!
Laravel already explodes your filter parameters on the comma, to allow passing multiple parameters to a filter. So, in your case, you've actually passed two parameters to your filter: the first parameter has the value 'Administrator', and the second parameter has the value 'Owner'.
So, two quick options are:
Change the delimiter you're using in your string. In your controller: $this->beforeFilter('role:Administrator;Owner'); and then in your filter: $roles = explode(';', $roles);
Or, leave your controller code alone and use PHP's func_get_args() function in your filter:
Route::filter('role', function($route, $request)
{
if(Auth::guest() !== true)
{
$roles = array_slice(func_get_args(), 2);
foreach($roles as $role)
{
if (Auth::user()->role->role_name == $role)
{
return;
}
}
return Redirect::to('/youshallnotpass');
}
});

Categories