I've used Eloquent hasOne to create a relationship between the user and the users_permissions table when the user register's to the website and group the user according to the input they put on the form and it worked fine, but the same method I think it does not recognize when the same user is signed in the website.
The below code work's when the user sign-up to the website
$user->permissions()->create(UserPermission::user_group($nature_of_entity));
But when I want to use the below method it, I get an error Trying to get property of non-object.
public function hasPermission($permission) {
return (bool) $this->permissions->$permission;
}
public function permissions() {
return $this->hasOne('App\User\UserPermission', 'user_id');
}
In the user database a table named users_permissions that has (id, user_id, is_group_one, is_group_two, is_group_three)
I'm trying to see it the user is in which group, like:
if($app->user->hasPermission('is_group_one')){
echo 'Group One';
}
But I get an error Trying to get property of non-object.
I'd really appreciate it if any can help and if they are ways I could do this and use Laravel Eloquent Relationships methods. I hope you can understand what I mean.
Create a scope that queries through the permissions relationship and checks if the column (i.e. $permission) is TRUE. Axe the (bool) bit...
public function scopeHasPermission($query, $permission)
{
return $query->permissions->where($permission, true);
}
Then in your controller, keep this the same as you had it:
if($app->user->hasPermission('is_group_one')) {
...
}
Related
I need to clear my doubt about Eloquent Relationships. I have 2 models User (which comes with Laravel) and Other is Role which I created.
in migration, I added role_id as an additional column as I want every user must have a role now I want to retrieve a user role based on user's id so, I created a public function named roles inside the User Model.
public function roles(){
return $this->belongsTo(Role::class);
}
now when i try to run the query like this.
App\User::find(1)->roles;
it won't return any result, just empty screen but when I change it to
public function role(){
return $this->belongsTo(Role::class);
}
after that i run code
App\User::find(1)->role;
now it returns the exact row where the user with id 1 has a proper role. it's confusing why with the roles() function it's not working but with the role() function it's working.
Sorry, If this question is already posted you can redirect me to that question.
Thank You!
You have to specify the foreign key
public function roles()
{
return $this->belongsTo(Role::class, 'role_id');
}
However, calling it role() is more accurate, since your are assuming that a User can only have one role.
I have three tables.
Users: id,name
Courses: id,user_id,name
Order: id,user_id,course_id (
Pivot table)
How can i make sure in course view that this user has purchased this particular course using Laravel eloquent.
Firstly, you need to define a many to many relationship between your models:
class User extends Model {
public function courses() {
return $this->belongsToMany(Course::class);
}
}
Once you have it, you can easily check if User has bought access to a Course with given ID with:
if ($user->courses()->find($courseId)) {
// user has access to course with given $courseId
}
If you simply want to an error to be raised when course was not bought, replace a call to find() with a call to findOrFail():
if ($user->courses()->findOrFail($courseId)) {
// user has access to course with given $courseId
}
Here is model structure of my Laravel 5.3 project,
User.php (Model)
it has one invitation method that returns the invitation of a user.
public function invitations()
{
return $this->hasMany( 'App\Invitation', 'invitee_id', 'id' );
}
Invitation.php (Model)
This model has another method that would return the inviter detail of an invitation.
public function inviter()
{
return $this->hasOne( 'App\User', 'id', 'invited_by' );
}
If i want to retrieve all invitations of current user it works,
\Auth::user()->invitations;
But if i try to get the information about the inviter it won't work! (Question: How to do it?)
\Auth::user()->invitations->inviter;
Though i can query the inviter from a invitation eloquent object like this,
\App\Invitation::first()->inviter;
But this is not working when i try to access it from the user model -> invitation -> inviter!
Also can i use eager loading here?
\Auth::user()->invitations->inviter;
Looking at this, it appears that you're attempting to retrieve the inviter property from a collection of invitations. The reason Ken's suggestion to use \App\Invitation::first()->inviter; worked is because you are retrieving the inviter of only one invitation (in this instance, the first). To resolve this, loop through your invites before attempting to retrieve the properties for each one:
$invitations = \Auth::user()->invitations;
foreach ($invitations as $invitation) {
$inviter = $invitation->inviter;
}
There is also an each() method specific to Laravel Collections that will allow you to loop through your object.
I want to create a relationship that checks if a user has liked a post. In order to do this, the relationship needs to check if the user is logged in, and then use their user_id to get the like record. Something like:
public function userLike() {
if (Auth::check()) return $this->hasOne('App\Like')->where('user_id', Auth::user()->id);
}
However, this doesn't work. Additionally, if the user is not logged in and this relationship is called (which it is by default), it will return an error.
What is the proper way of doing this?
If you want to conditionally load a relation then you can do so by lazy eager loading. In your example you could define the relation as
public function userLike() {
return $this->hasOne('App\Like', 'user_id');
}
Then in your controller (or wherever else) you can do the check for if the user is question is currently logged in user or not
$loggedInUser = auth()->user();
if($loggedInUser){
$loggedInUser->load('userLike');
}
Then you can continue with whatever you want to do with the loggedInUser and the userLike.
Say you have multiple users at a point (in your code) and you want to load the likes for only the currently logged in user then you can
//$users is a collection of multiple users - assumed
foreach($users as $user){
if($user->email === auth()->user()->email){
$user->load('userLike');
}
}
Hope this helps
This is how I would do that:
1) “likes” table
I would first create a table to store all the “likes” with columns for a “post_id” and a “user_id”
2) create the relationships
User Model
public function likes()
{
return $this->belongsToMany('App\Post', 'likes', 'user_id', 'post_id');
}
Post Model
public function likes()
{
return $this->belongsToMany('App\User', 'likes');
}
3) Post Controller - the method
I would do the followings:
check if user is logged in, otherwise throw an error
make sure post exists, otherwise throw an error
create a new entry in like table with user_id and post_id
(you can also check if the user is logged in directly on your route using a middleware)
4) In the view
I would call the controller method using an ajax call.
Not sure if I forgot something, but hopefully that can help you a little bit.
If you need to “like” more things than only post, check the polymorphic relationships.
Database Structure:
-Users Table
-user_id
-name
-...
-Follow Table
-user_id
-follow_id
so when user follow another it will be inserted in follow table
and when get user followers
$user = User::where('user_id',$id)->first();
$user['followers'] = $user->Followers;
$user['following'] = $user->Following;
return $user;
By This Relation in User Model Side
public function Followers()
{
return $this->hasMany('App\Follow','follow_id','user_id');
}
And By This Relation in Follow Model Side
public function getUserData()
{
return $this->belongsTo('App\User','user_id','user_id');
}
It Works Fine for me and it gaves me every id But the problem is
that i want to get information about every user returned from this relation
so i should call User Model for each user returned to get his information
or what ??
The way you have you many-to-many relationship set up is almost right.
Firstly, change the Followers() method to be followers() as Laravel follows the PSR-2 standard.
Secondly, this isn't essential but change the user_id column in the users table to be just id. This is a laravel convension that does not need to be followed, however, at this point I don't see any reason not to follow it. I am assuming that you have something like:
protected $primaryKey = 'user_id';
in your User model. If you change your user_id column to id you won't have to have the above declaration anymore.
(If you don't have that line in and you want to continue using user_id as the primary key you WILL have to add that line to your User model.
Thirdly, change the relationship type in followers() to be:
public function followers()
{
return $this->belongsToMany('App\User', 'follower', 'user_id', 'follow_id');
//follower is the table name, user_id is column that relates to the current model and follow_id is the column that is for the relationships
}
With all of the above done you can now get a user with all of their followers by doing:
$user = User::with('followers')->find($id);
This will allow you to get the followers by simply doing:
$user->followers
At this point you can not get rid of you Follow model as you generally wont need a model for a pivot table.
To get the following relationship just add:
public function following()
{
return $this->belongsToMany('App\User', 'follower', 'follow_id', 'user');
}
to your User model.
Again to access this you can either:
$user = User::with('following')->find($id);
or if you have already have the user model and the relationship isn't loaded you can:
$user->load('following'); //in this case following is the name of the method where you have declared the relationship.
For more information please refer to the documentation http://laravel.com/docs/5.1/eloquent-relationships#many-to-many and http://laravel.com/docs/5.1/eloquent
Hope this helps!