Laravel hasOne get only one field instead of object - laravel

There two models user and also address, which contains country, city and etc. I need to get a list of users with the city, not with the whole address. Relation is oneToOne. The only thing I can get, using select['user_id', 'city']:
{
"id": 1,
"name": "John",
"city": {
"user_id": 3,
"city": "Paris"
},
but I need:
{
"id": 1,
"name": "John",
"city": "Paris"
}
Of course, I can use a loop and do something like $user->city = $user->address->city but maybe there is a better way to solve this problem. Laravel 5.4

You can use Accessor,
And append the attribute to json appending-values-to-json:
In your User model:
protected $appends = ['city'];
public function getCityAttribute()
{
return $this->city->city;
}
Test it like this:
User::with('city')->get()->toJson();
// It will return:
// [{"id": 1, "name": "John", "city": "Paris", "city" : {"user_id": 3, "city": "Paris"}}, {...}]

Related

Strapi Graphql query with filtering/conditional rendering

In my Strapi project, i'm trying to write a Graphql query that filters posts by an array of tags.
The post has to belong to all tags of the given array.
E.g. the post below would not meet the condition if given array is [1,2,3] but would pass the condition if array is [3,5].
Any help would be much appreciated
Example Post:
{
"id": "1",
"title": "Lorem Iopsum",
"created_at": "2021-02-19T22:53:19.204Z",
"tags": [
{
"id": "3",
"tag": "Porte De Gentily"
},
{
"id": "5",
"tag": "Bridges"
},
{
"id": "6",
"tag": "Towers"
}
]
}
I was trying something like:
query {
posts( where: {tags: {id_contains: [3,1]}}) {
title
tags{id},
created_at
}
}
You can do it something like this
query($ids:[ID]) {
posts( where: {tags: {id:$ids}}) {
title
tags{id},
created_at
}
}
And pass your ids as a query variable:
{
"ids": [1,5]
}

Laravel get only one column from relation

I have a table user_childrens whose contains id_parent and id_user.
I'm trying to list all childrens of the parent with this:
code:
//relation in model via belongsTo
$idparent = auth('api')->user()->id;
$list = UserChildren::where('id_parent',$idparent)
->with('child:id,name,email')
->get();
return $list->toJson();
The return is:
[
{
"id": 1,
"id_parent": 1,
"id_user": 1,
"created_at": null,
"updated_at": null,
"child": {
"id": 1,
"name": "Mr. Davin Conroy Sr.",
"email": "prempel#example.com"
}
},
{
"id": 4,
"id_parent": 1,
"id_user": 2,
"created_at": null,
"updated_at": null,
"child": {
"id": 2,
"name": "Krystel Lehner",
"email": "cernser#example.net"
}
}
]
But it's API so I want only the child column like:
[
{
"id": 1,
"name": "Mr. Davin Conroy Sr.",
"email": "prempel#example.com"
},
{..}
]
UserChildren Model:
public function child() {
return $this->belongsTo('App\User','id_user','id');
}
I know that I could do this via .map() on collection but maybe there is other solution already on this query
You can use this code
$idparent = auth('api')->user()->id;
$childs = User::whereHas('user_childrens', function ($query) use ($idparent) {
$query->where('id_parent', $idparent);
})->get(['id', 'name', 'email']);
dd($childs->toJson());
And User model define user_childrens relation.
public function user_childrens()
{
return $this->hasMany('App\UserChildren','id_user','id');
}
See also docs https://laravel.com/docs/5.5/eloquent-relationships#querying-relationship-existence

hasManyThrough is returning only one result instead of all

The platform has a many to many relationship, where the table assigned_users holds all Users assigned to CalendarEvents.
I need to fetch, through CalendarEvents, the assigned users as an object, showing each user's information. So, I want to access the User through AssignedUsers, because I wanna fetch all the users related to that event.
public function assignedUsers()
{
return $this->hasManyThrough(Users::class, AssignedUsers::class, 'user_id', 'id');
}
It works, but it shows only the first user in the table. I want to show all of them. Currently there are 3.
"assigned_users": [
{ id: 1, ... }
]
If I do the following:
public function assignedUsers()
{
return $this->belongsToMany(Users::class, "assigned_users", "event_id", "event_id");
}
It will fetch 3 results, but all the information will be from the same user. It will repeat the same user 3 times. Changing both the event_id to user_id and id, and id and user_id will have the same result.
"assigned_users": [
{ id: 1, ... },
{ id: 1, ... },
{ id: 1, ... },
...
]
What I am trying to accomplish is the following result:
{
"status": "200",
"success": true,
"data": [
{
"event_id": 1,
"event_key": "EB1M7OGJRPW0",
"calendar_id": 4,
"start_at": "2018-01-01 00:00:00",
"end_at": "2018-01-31 00:00:00",
"location": "123 Lorem, Ipsum",
"event_name": "Event #1",
"description": "Lorem ipsum dolor sit amet",
"added_at": "2018-02-07 09:07:31",
"created_by": {
"id": 4,
"name": "Foo Bar",
"email": "foobar92#gmail.com",
"first_name": "Foo",
"last_name": "Bar",
"status": "active",
"is_activated": 0,
"created_at": "2018-02-07 09:06:49",
"updated_at": "2018-02-07 09:06:49"
},
"assigned_users": [
{
"id": 1,
...
},
{
"id": 2,
...
},
{
"id": 3,
...
},
...
]
}
]
}
This is not the case of hasManyThrough relationship. Here assigned_users is a pivot table so you just need a belongsToMany relationship defined
public function assignedUsers()
{
return $this->belongsToMany(Users::class, 'assigned_users', 'event_id', 'user_id');
}
and for this to work, you may have to change the calendar_events table's primary key to id (instead of event_id)

Extract mentioned users in post like Facebook comment

I followed this Laracast tutorial - https://laracasts.com/series/lets-build-a-forum-with-laravel/episodes/56 - to get "mentions" inside body. However I now want to fetch all the data for a thread, so I want all posts, and all related users, specifically mentioned users.
I am fetching all posts like this:
public function get(Thread $thread) {
return $thread->with(['posts'=>function($query) { return $query->with('user'); }]);
}
This returns to me data like this:
{
"id": 1,
"posts": [
{
"id": 1,
"user_id": 13,
"body": "Hi #14 and #15",
"user": {
"id": 13,
"name": "Joe"
}
},
{
"id": 2,
"user_id": 14,
"body": "Hi back at you"
"user": {
"id": 14,
"name": "Bob"
}
}
]
}
We see I get the author user's just fine. But I also need the mentioend users.
We see in the first one, during the store process, I converted #string to #USER_ID.
I did this in the store:
preg_match_all('/\#[^\s\.]+)/', $post->body, $matches);
And repalced with user_id.
Now however on fetch, I want to extract the user_id's from the post and attach to the resulting data these users. Is this possible?
My goal:
{
"id": 1,
"posts": [
{
"id": 1,
"user_id": 13,
"body": "Hi #14 and #15",
"users": [
{
"id": 13,
"name": "Joe"
},
{
"id": 14,
"name": "Bob"
},
{
"id": 15,
"name": "Ryan"
}
},
{
"id": 2,
"user_id": 14,
"body": "Hi back at you",
}
]
}
Is there a way to run the regex on each body and select the mentioned users too?
I think your goal isn't the correct one. You should think a good database design.
In your case, It's good to have mentions relation in your post (not users). Then you can attach the mentioned users to the post mentions. Something like,
preg_match_all('/\#[^\s\.]+)/', $post->body, $matches);
// get the author of the post
$author = $request->user();
// get all the user account for every #, except the author itself
$mentions = User::where(function ($query) use ($matches) {
foreach ($matches as $item) {
$query->orWhere('username', 'LIKE', $item);
}
})->where('id', '!=', $author->id)->get();
// attach the author to the post
$post->user()->save($author);
// attach $mentions to the post
$post->mentions()->saveMany($mentions);
// notify user were mentioned
Notification::send($mentions, new YouWereMentioned($post));
then to fetch the posts, you can do like so,
public function get(Thread $thread) {
return $thread->with([
'posts'=> function($query) {
return $query->with('user', 'mentions');
}
]);
}
Note. The laracasts video is only for the subscriber. You shouldn't make a question using a private resource. Or you must explain it all.

Laravel eager loading with field limit

I have three tables:
users
id
name
role_id
password
...
role_user
id
role_id
user_id
roles
id
name
slug
...
Now I want to get a user list with users.id,users.name,
roles.id. That's my code:
$query = User::with(['roles'=>function($q){
$q->lists('role_id');
}])->get(['id','name']);
the response like that
{
"id": "1",
"name": "aaaa",
"roles": []
},
{
"id": "2",
"name": "bbbb",
"roles": []
},
when i don't pass the array to get method,the response like that:
{
"id": 1,
"name": "aaaa",
"password": "xxxxxxx",
"created_at": "2015-05-07 14:15:00",
"roles": [
{
"role_id": 2,
"pivot": {
"user_id": 1,
"role_id": 2
}
}
]
},
{
"id": 2,
"name": "bbbb",
"password": "xxxxxxx",
"created_at": "2015-05-05 14:15:00",
"roles": [
{
"role_id": 2,
"pivot": {
"user_id": 2,
"role_id": 2
}
}
]
},
But i do not want the password,created_at and pivot field. How to filter these?
To get relations you need to get the foreign keys. Try this
$query = User::with(['roles'=>function($q){
$q->get(['id', 'name', 'slug']);
}])->get(['id','name', 'role_id']);
As for the pivot table, can you post you roles relation in the user model?
Edit
Add this to your user model to hide the pivot properties
protected $hidden = ['pivot'];
You can add more fields to that property to remove them from all queries.

Resources