Laravel 5.4 with Entrust: How to get users with roles - laravel

I am trying to get all users with roles, but "roles" field is always an empty array.
There are 4 users, 2 of them have at least 1 role attached, verified.
UserController.php
public function getUsers()
{
$users = User::select('name', 'email', 'type')->with('roles')->get();
return view('user.list', ['users' => $users, 'lang' => Lang::getLocale()]);
}
I get the 'roles' field as an empty array, even if I don't use "with->('roles')" in the controller. Weird?
If i print each user role in the view, I get this:
object(Illuminate\Database\Eloquent\Collection)#281 (1) { ["items":protected]=> array(0) { } }
What I am doing wrong?

You have to select also primary key, on which roles are related.
Eloquent is first selecting all users and then based on their IDS (primary and foreign) is selecting relations. If you dont select primary key, he cant relate relations.
$users = User::select('id', 'name', 'email', 'type')->with('roles')->get();
Also, if you want specifi which columns from roles you want, you have to select foreign key too.
$users = User::select('id', 'name', 'email', 'type')->with(['roles' => function ($query) {$query->select('id', 'name', 'user_id');}])->get();

Related

Cakephp 3 filter by a many to many associated relation

I have a users table, roles and users_roles as a join / pivot table. I am tryin to create a query to retrive all the users that HAVE NOT these roles: interventor, editor, chief
At the moment this is my query but I am not getting the desiered results, because users with these roles still coming.
$users = TableRegistry::getTableLocator()->get('Users');
$allUsers = $users->find('all', ['order' => ['Users.id ASC']])->select([
'id',
'name',
'surname',
])
->contain('Roles', function (Query $q) {
return $q
->select(['slug'])
->notMatching('Users.Roles', function ($q) {
return $q->where(['Roles.slug NOT IN' => ['interventor', 'editor', 'chief']]);
});
});
Thank you
Ok I found asolution.
Just adding an innerJoin to the query.
->innerJoinWith('Roles')->where(['Roles.slug NOT IN' => ['interventor', 'editor', 'chief']]);

How do I return the ID field in a related table in Laravel request

I have two related tables and I want to return all fields including the ID (key) field. My query below returns all fields except the ID. how do I return the ID field from one of the tables?
'programmes' => ProgrammeInstances::with('programmes')->get(),
the query below returns Unknown column 'programmes.programme_title' as it is looking for it in the table 'programme_instances'
'programmes' => ProgrammeInstances::with('programmes')->select('programmes.programme_title', 'programmeInstances.id', 'programmeInstances.name', 'programmeInstances.year')->get(),
Laravel provides multiple relationships, one of these is the hasMany() relationship which should return a collection where a User hasMany rows inside of your database
For example, inside your User model :
public function programmes() {
return $this->hasMany(Program::class);
}
Now in your controller, you can do :
public function edit($id) {
$programmes = User::find($id)->with('programmes')->get();
return view('user.edit')->with('programmes', $programmes);
}
And then you can loop over it inside your view
#forelse($programmes->programmes as $program)
// provide the data
#empty
// the user doesn’t have any programmes
#endforelse
a solution i found below - still not sure why ID isnt automatically returned when i get all fields, but works when i specify individual fields:
'programmes' => ProgrammeInstances::with('programmes')
->get()
->transform(fn ($prog) => [
'programme_title' => $prog->programmes->programme_title,
'id' => $prog->id,
'name' => $prog->name,
'year' => $prog->year,
]),

How to scope results with pivot table October Cms

The solution to this is probably easy and I'm just missing it, but I can't seem to figure out how to limit "customers" based on the "user" that the customer belongs to.
This is a many to many relationship, so a customer can belong to more than one user and a user can have more than one customer.
Here is my relationship definition:
public $belongsToMany = [
'user_id' => [
'RainLab\User\Models\User',
'table' => 'tablename_users_customers',
]
];
And here is the scope function that doesn't work as I'd expect:
public function scopeUser($query) {
$user = Auth::getUser()->id;
return $query->where('user_id', $user)->get();
}
Finally, here is my error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'user_id' in 'where clause' (SQL: select * from `tblcustomers` where `user_id` = 1)
Obviously, the error is because the "user_id" column doesn't exist in the 'tblcustomers' table, but rather in the pivot table. How can I use the "user_id" from the pivot table in my scope function? I need to only display Customers that belong to the currently logged in user.
Yes this can be possible
But First thing is you need to remove get() method from the scope, scope meant to return query object for chaining methods further.
Your relation and scope should look like this
// relation
public $belongsToMany = [
// PLEASE MAKE RELATION NAME CORRECT HERE
'users' => [ // not user_id, use `users`
'RainLab\User\Models\User',
'table' => 'tablename_users_customers',
// 'key' => 'customer_id', if needed
// 'otherKey' => 'user_id' if needed
]
];
// scope
use RainLab\User\Models\User;
public function scopeUser($query) {
return $query->whereHas('users', function($usersQuery) {
$user_id = Auth::getUser()->id;
return $usersQuery->where((new User)->getTable() . '.id', $user_id);
});
}
// usage
$result = Customer::user()->get();
dd($result);
// you will get only customers which has relation with current logged in user.
if any doubts please comment.

How to associate comments to users on Laravel?

public function store(Post $post)
{
$this->validate(request(), ['body' => 'required|min:2']);
$post->addComment(request('body'));
return back();
}
this is my code
I am having this error
SQLSTATE[HY000]: General error: 1364 Field 'user_id' doesn't have a default value (SQL: insert into comments (body, post_id, updated_at, created_at) values (ewrtyuttrew, 1, 2018-02-15 15:44:17, 2018-02-15 15:44:17))
You need to add a user who created the comment manually. For example:
public function addComment(string $body)
{
$this->comments()->create(['body' => $body, 'user_id' => auth()->id()]);
}
In your User model you can define the relationship as:
public function comments() {
return $this->hasMany(Comment::class);
}
So, if the user it's the logged user, then you can retrieve it with the Auth facade:
$user = Auth::user();
Then you can simply do:
$user->comments()->save(new Comment(request('body'));
Note that you must set the "fillable" fields on the Comment model in order to allow the dynamic creation.
Field 'user_id'
Open phpmyadmin and open comments table then after
Field 'user_id' => auto increment and primary key add
Try this I solve this type issues, thanks

Algolia search (Scout) with multiples fields

Let' say I want to create a phone book for a big company with multiples offices.
My database is composed by 3 tables:
- User
- City (represent the office's location)
- Role (a User can have multiple roles)
I'd like to create a form with 3 different fields to perform the query, how can I do that ?
For now I've got only 1 field and this is my main model User
```
public function city()
{
return $this->belongsTo(City::class);
}
public function roles()
{
return $this->belongsToMany(Role::class);
}
public function toSearchableArray()
{
$office = $this->city;
$array = [
'name' => $this->name,
'phone' => $this->phone,
'postal_code' => $office->postal_code,
'city' => $office->name,
];
return $array;
}
```
How would you do a research with Algolia and add filters to the query (City and Roles) ?
How should I store Roles ? Plain text ?
Thank you
Scout only support numbers in the where clause: https://laravel.com/docs/5.5/scout#where-clauses
I would recommend to also store the ID for offices and do search like:
User::search('')->where('office_id', 2)->get();
For Roles, because you have multiple values, you should store them as in an array.
You cannot use where on arrays, so you will need to leverage the callback parameter to add a filter entry in the options array.
User::search('', function ($algolia, $query, $options) {
$options = array_merge($options, [
'filters' => 'roles:engineer'
]);
return $algolia->search($query, $options);
})->get();
You can find Algolia's doc about filtering here: https://www.algolia.com/doc/guides/searching/filtering/
Please let me know if that worked for you.

Resources