I need to check if the data is exist and get data after that
Exam:
Loc::fisrt()->user()->exists()->get(); // This is just an example, it's not true
->get after exists this i need
I hope my question is clear.
Just get the data and check it afterwards.
$user = Luc::first()->user;
If user() is a belongsTo, hasOne or morphOne relationship:
if ($user !== null) { /* user exists */ }
If user() is a belongsToMany, hasMany, hasManyThrough, morphMany, morphToMany or morphedByMany relationship:
if ($user->isNotEmpty()) { /* user exists */ }
There is a perfect solution for what you need in Eloquent already. The has method.
$results = Loc::has('user')->get();
The above results will only contain Loc records that have a user relation attached to them.
Related
I created many-to-many relationship between User model and Role model with the pivot table 'role_user'. I want to retrive a single column 'role_name' for the authenticated user as an array.
Here's my configuration for User and Role model:
User.php:
public function roles()
{
return $this->belongsToMany(Role::class);
}
Role.php:
public function users()
{
return $this->belongsToMany(User::class);
}
AuthController.php:
public function details()
{
$user = Auth::user();
$user['role'] = $user->roles;
return response()->json(['success' => $user], 20);
}
To which laravel responds with the following:
{"user":{"id":4,"first_name":"Jill","last_name":"mclane","email":"jill#g.co","role":[{"id":1,"role_name":"vendor","pivot":{"user_id":4,"role_id":1}}]}}
I want to get role_name column as an array for a selected user. eg. role:['vendor','admin']. I used select method but it returns pivot along with other columns:
$user['role'] = $user->roles()->select('role_name')->get();
//returns {"user":{"id":4,"first_name":"Jill","last_name":"mclane","email":"jill#g.co","role":[{"role_name":"vendor","pivot":{"user_id":4,"role_id":1}}]}}
You can use the pluck method on the Collection to do this:
$user['role'] = $user->roles->pluck('name');
You have loaded the roles relationship when accessing $user->roles though. Though it is not showing in your current output.
This method also exists for Query Builder.
$user['role'] = $user->roles()->pluck('name');
This would not load the relationship.
Laravel 7.x Docs - Collections - Available Methods pluck
Laravel 7.x Docs - Queries - Retrieving Results - Retrieving A List Of Column Values pluck
use first() function to get single record
$user['role'] = $user->roles()->first()->role_name;
An easy and good way to approach something like this would be to use API resources. That way you can customize the JSON response from the controller.
See: https://laravel.com/docs/7.x/eloquent-resources
My comments table has the following columns:
id, user_id, image_id, comment
Currently I'm getting all comments that belong to a specific image like this:
$comments = Comment::where('image_id', $id)->get();
And then I can easily display the comments on the view to which I pass the $comments variable. However, I can only display the id of the user who has posted the comment but that wouldn't make much sense so I'm trying to display the username instead.
Since I don't save the username of the user who has posted a comment in the comments table, I can't access it from $comments as of now. Is there a way to somehow add an extra key-value pair to $comments that would contain the username of the user based on his id?
Comment model:
class Comment extends Model
{
public function images(){
return $this->belongsTo('App\Image');
}
public function users(){
return $this->belongsTo('App\User');
}
}
User model:
class User extends Model implements Authenticatable
{
public function comments(){
return $this->hasMany('App\Comment');
}
}
I guess that you should have a table/model for the User objects.
If so, you can Eager Load the relationship. To accomplish this, define the relationship in your model:
app/Comment.php
public function users()
{
return $this->belongsTo(User::class);
}
Note: given that this is the reverse of a hasMany relationship (belongsTo), you should name this functions in singular: a Comment belongs to a unique User.
Then in your controller:
$comments = Comment::with('users')->where('image_id', $id)->get();
This will include the user object inside every comment. Of course, you can limit the user attributes returned to the view but you get te idea.
To know more about this, check the documentation.
Make a Join similar to connect both tables!
$comments = DB::table('comment')
->join('user', 'comment.user_id', '=', 'user.id')
->select('comment.*', 'user.name')
->where(image_id, $id)
->get();
A related question with eloquent specifics
How to join three table by laravel eloquent model
i have three models
Article
id
title
Comment
id
title
user_id
article_id
User
id
name
what i wanna achieve is to select one article based on its id with comments and user info that made that comment
like that :
$article = Article::find($id -- say 1)->with('comments' -- this is a relation in Article Model)->get();
this gives me article with related comments as an array of objects say comment one - comment two etc ....
what i want instead of user_id in comment object i wanna it to be a user object
see this pic thats what i reached so far
using laravel 5.4
You can use following:
$articles = Article::find($id)->with('comments', 'comments.user')->get();
Here 'user' is the relationship you mentioned in the comments model for User.
If you have defined the foreign key relationship in Schemas, you can define functions for Eloquent Relationship as defined in following reference link -
Laravel - Eloquent Relationships.
You can define functions in models as follows -
Article -
class Article extends Model
{
...
public function comments(){
// Accessing comments posted to that article.
return $this->hasMany(\App\Comment::class);
}
// Create a foreign key to refer the user who created the article. I've referred it here as 'created_by'. That would keep relationship circle complete. You may ignore it if you want.
public define user(){
// Accessing user who posted the article
return $this->hasOne(\App\User::class, 'id', 'created_by');
}
}
Comment -
class Comment extends Model
{
...
public function article(){
// Accessing article to which the particular comment was posted
return $this->hasOne(\App\Article::class, 'id', 'article_id');
}
public function user(){
// Accessing user who posted the comment
return $this->hasOne(\App\User::class, 'id', 'user_id');
}
}
User -
class User extends Models
{
...
public function articles(){
// Accessing articles posted by a user
return $this->hasMany(\App\Article::class);
}
public function comments(){
// Accessing comments posted by a user
return $this->hasMany(\App\Comment::class);
}
}
Now you can use like following -
$article = Article::findOrFail($id);
$comments = $article->comments;
$article_user = $article->user;
$comment_user = Comment::findOrFail($commnet_id)->user;
$users_comments = User::findOrFail($user_id)->comments;
$users_articles = User::findOrFail($user_id)->articles;
and so on...
It is far better to use ->find() at last instead of ->get() because get() returns a Collection.
This way you will get a single object which you want instead of a Collection.
For example:
$commentableObj = Post::with(['comments'])
->withCount(['comments'])
->findOrFail($commentable->id);
I have the following schema set up:
users:
id
departments:
id
department_user:
id
department_id
user_id
I also have the following relationships set up:
User Model
public function departments()
{
return $this->belongsToMany('App\Resources\Eloquent\Models\Department', 'department_users');
}
Department Model
public function users()
{
return $this->belongsToMany(User::class, 'department_users');
}
For some reason, when I am trying to access through the user model $user->departments, it doesn't work - but $department->users does.
Outputting the eloquent query is as follows:
select `departments`.*, `department_users`.`user_id` as `pivot_user_id`, `department_users`.`department_id` as `pivot_department_id` from `departments` inner join `department_users` on `departments`.`id` = `department_users`.`department_id` where `department_users`.`user_id` is null
I can't seem to figure out why it is looking to see if department_users.user_id is null, when it should be looking for the user's id.
Any ideas?
Why don't you set up your models like it is suggested in the documentation here:
So your models would look something like this:
User Model
public function departments()
{
return $this->belongsToMany('path\to\your\model\Department');
}
Department Model
public function users()
{
return $this->belongsToMany(path\to\your\model\User);
}
Eloquent will join the two related model names in alphabetical order.So you don't need extra arguments when defining your relationship and Laravel also by default, makes model keys present on the pivot object. And then you can do something like this:
$department = path\to\your\model\Department::find(1);
foreach ($department->users as $user) {
echo $user;
}
For some reason, if I make the relationship the following - it works.
return $this->belongsToMany(Department::class, 'department_users')->orWhere('department_users.user_id', $this->id);
If anyone knows why, please let me know
I'm trying to create a Friendship system with Laravel (I'm starting with it) but I'm blocked with relationships. Here's the thing : there is one table Users and one table Friends which contains the following columns :
friends: id, user_id, friend_id, accepted.
It looks like a Many to Many so here's what I set on User class :
class User extends Eloquent {
function friends()
{
return $this->belongsToMany('User');
}
}
But when I try a :
$friends = User::find($id)->friends()->get()
I have this error :
Base table or view not found: 1146 Table 'base.user_user' doesn't exist
I would like to get a list of the Friends of a user, no matters if the user sent the invitation or received it. So the user can ba on user_id or on friend_id and then I retrieve the data of the other user depending of that column.
Any idea? Thank's!
EDIT : Here's the code I use :
$usersWithFriends = User::with('friendsOfMine', 'friendOf')->get();
$user = User::find(Auth::id())->friends;
foreach($user as $item) {
echo $item->first()->pivot->accepted;
}
tldr; you need 2 inverted relationships to make it work, check SETUP and USAGE below
First off the error - this is how your relation should look like:
function friends()
{
return $this->belongsToMany('User', 'friends', 'user_id', 'friend_id')
// if you want to rely on accepted field, then add this:
->wherePivot('accepted', '=', 1);
}
Then it will work without errors:
$user->friends; // collection of User models, returns the same as:
$user->friends()->get();
SETUP
However you would like the relation to work in both ways. Eloquent doesn't provide a relation of that kind, so you can instead use 2 inverted relationships and merge the results:
// friendship that I started
function friendsOfMine()
{
return $this->belongsToMany('User', 'friends', 'user_id', 'friend_id')
->wherePivot('accepted', '=', 1) // to filter only accepted
->withPivot('accepted'); // or to fetch accepted value
}
// friendship that I was invited to
function friendOf()
{
return $this->belongsToMany('User', 'friends', 'friend_id', 'user_id')
->wherePivot('accepted', '=', 1)
->withPivot('accepted');
}
// accessor allowing you call $user->friends
public function getFriendsAttribute()
{
if ( ! array_key_exists('friends', $this->relations)) $this->loadFriends();
return $this->getRelation('friends');
}
protected function loadFriends()
{
if ( ! array_key_exists('friends', $this->relations))
{
$friends = $this->mergeFriends();
$this->setRelation('friends', $friends);
}
}
protected function mergeFriends()
{
return $this->friendsOfMine->merge($this->friendOf);
}
USAGE
With such setup you can do this:
// access all friends
$user->friends; // collection of unique User model instances
// access friends a user invited
$user->friendsOfMine; // collection
// access friends that a user was invited by
$user->friendOf; // collection
// and eager load all friends with 2 queries
$usersWithFriends = User::with('friendsOfMine', 'friendOf')->get();
// then
$users->first()->friends; // collection
// Check the accepted value:
$user->friends->first()->pivot->accepted;
It's oviously a problem in your DB and also definition of the relation. Many-to-Many relation type expects you to use and intermediate table. Here's what you have to do :
Create a user_friend (id, user_id, friend_id) table in your schema.
Remove unnecessary fields from user and friend tables.
Create proper foreign keys . user.id-> user_friend.user_id , friend.id -> user_friend.friend_id
Better define full relation on the User and Friend models,
for example :
class User extends Eloquent {
function friends()
{
return $this->belongsToMany('User', 'user_friend', 'user_id', 'friend_id');
}
}
You can read much more in Laravel docs, HERE