How do I add like numbers to my API column? - laravel

we are preparing a mobile application with Laravel infrastructure. I am using the related tables in my api source and I want to add the number of user comments and likes to this api source in addition. How can I do that?
In addition, I would like to receive comments posted on related user's topics and user information that gives likes to my api source.
Likes Table: id, user_id, post_id
Comments Table: id, user_id, post_id, description
Function
public function user_posts($id)
{
return DB::table('posts')
->leftJoin('users', 'posts.user_id', '=', 'users.id')
->leftJoin('likes', 'likes.user_id', '=', 'users.id')
->where('posts.user_id', '=', $id)
->select('posts.*', 'posts.user_id', 'posts.description', 'likes.user_id as like_user_id', 'likes.post_id as like_post_id')
->get();
}
URL: http://warm.test/api/users/6/posts
Route: Route::get('/users/{id}/posts/like', [LikeController::class, 'like_show'])->name('users.like_show');
Output:
[
{
"id": 6,
"user_id": 6,
"image": "https://lorempixel.com/800/400/cats/warem/?39492",
"description": "Laboriosam rem unde velit nihil. Hic enim quidem necessitatibus eum aut voluptates. Molestiae voluptas voluptas nam neque qui illum. In autem aut illo sunt cumque numquam. Sit quia rerum maiores eius. Et ut aut inventore omnis tenetur ut eveniet delectus.",
"created_at": "2015-04-04 07:51:39",
"updated_at": "2020-12-25 08:55:40",
"like_user_id": 6,
"like_post_id": 6
},
{
"id": 6,
"user_id": 6,
"image": "https://lorempixel.com/800/400/cats/warem/?39492",
"description": "Laboriosam rem unde velit nihil. Hic enim quidem necessitatibus eum aut voluptates. Molestiae voluptas voluptas nam neque qui illum. In autem aut illo sunt cumque numquam. Sit quia rerum maiores eius. Et ut aut inventore omnis tenetur ut eveniet delectus.",
"created_at": "2015-04-04 07:51:39",
"updated_at": "2020-12-25 08:55:40",
"like_user_id": 6,
"like_post_id": 5
}
]

As you said you are on Laravel I recommend you to use Laravel Eloquent, it makes things much easier.
In your case we need Post, Like and Comment models.
Like class:
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use App\Models\Post;
class Like extends Model
{
// Define relationships here
public function post()
{
return $this->belongsTo(Post::class);
}
}
Comment class:
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use App\Models\Post;
class Comment extends Model
{
public function post()
{
return $this->belongsTo(Post::class);
}
}
Post class:
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use App\Models\Like;
use App\Models\Comment;
class Post extends Model
{
public function likes()
{
return $this->hasMany(Like::class);
}
public function comments() {
return $this->hasMany(Comment::class);
}
}
Your controller action method:
public function userPosts($id)
{
return Post::withCount('likes', 'comments')->where('user_id', '=', $id)->get();
}
Example output:
[
{
"id": 6,
"user_id": 6,
"image": "https://lorempixel.com/800/400/cats/warem/?39492",
"description": "Laboriosam rem unde velit nihil. Hic enim quidem necessitatibus eum aut voluptates. Molestiae voluptas voluptas nam neque qui illum. In autem aut illo sunt cumque numquam. Sit quia rerum maiores eius. Et ut aut inventore omnis tenetur ut eveniet delectus.",
"created_at": "2015-04-04 07:51:39",
"updated_at": "2020-12-25 08:55:40",
"likes_count": 6,
"comments_count": 2
},
...
]

Related

Using filter in a Laravel collection

This is the following code:
$apartment_list->filter(function ($apartament) use ($services) {
if (isset($apartament) && $apartament->services[0]->id = $services) {
return $apartament;
}
});
this is an example of my $apartment_list:
{
"id": 1,
"user_id": null,
"title": "Non sunt vitae quia.",
"slug": "non-sunt-vitae-quia",
"rooms": 3,
"bathrooms": 2,
"beds": 11,
"squared_meters": 50,
"address": "14235 Emory Villages Suite 671\nMillerbury, RI 40415-0580",
"latitude": "-75.191525",
"longitude": "-105.046424",
"image": "https://via.placeholder.com/800x800.png/0011aa?text=eveniet",
"is_visible": 1,
"floor": 4,
"price": 1138,
"description": "Dolor fuga cumque delectus doloremque ratione minima. Ut voluptatum porro id et est nam. Dolor unde corrupti excepturi ratione quo.\n\nVoluptatem mollitia omnis ipsa tempore nihil nisi. Ut ullam ut et unde. Est dolores tempore molestiae est omnis.\n\nEst autem ut porro voluptas qui. Ducimus possimus quia vel a beatae id eligendi. Facilis accusamus velit tempora et explicabo architecto. Dolorem at quia esse ipsa officiis est reiciendis.\n\nVoluptate voluptatum minus qui ut velit. Voluptas et quis sint modi culpa. Odit est qui est unde sequi. Eveniet et voluptates est vero.",
"created_at": "2022-02-22T21:26:06.000000Z",
"updated_at": "2022-02-22T21:26:06.000000Z",
"services": [
{
"id": 1,
"name": "WiFi",
"slug": "wifi",
"created_at": "2022-02-22T21:26:06.000000Z",
"updated_at": "2022-02-22T21:26:06.000000Z",
"pivot": {
"apartment_id": 1,
"service_id": 1
}
}
],
"sponsors": []
},
this code simply transform my services id to 1, without doing his job.
how can I fix it?
I'd like to know also how write better $apartament->services[0]->id to have access at my attributes.
Try this one
apartment_list->filter(function ($value, $key) use ($services) {
return $apartament->id === $value->id;
});

Laravel API Customizing associated columns

I have an api source that I combined in related tables. I have customized the objects, but I cannot customize the associated data in it. How do I do this?
Previous Output:
{
"id": 1,
"user_id": 3,
"image": "https://localhost/800/400/cats/varem/?20215",
"description": "Omnis eius corporis incidunt illo dolor et est odio. Et fuga hic id. Velit voluptas tempore quas voluptas iusto. Quia rerum quibusdam consectetur distinctio vero. Nihil et sed reiciendis sequi. Possimus facere ducimus provident est. Qui ut rerum ab ullam sequi est. In placeat nesciunt odio numquam iure.",
"created_at": "2017-09-18T10:51:17.000000Z",
"updated_at": "2020-12-25T08:55:40.000000Z",
"likes": [
{
"id": 7,
"user_id": 10,
"post_id": 1,
"created_at": "1970-03-31T14:17:28.000000Z",
"updated_at": "2020-12-25T08:55:40.000000Z"
}
]
}
Function:
public function like_show($id) {
return Posts::selectRaw('id as post_id, user_id, image as post_image, description as post_description, created_at')
->with('likes')
->where('user_id', '=', $id)
->get();
}
Next Output:
{
"post_id": 1,
"user_id": 3,
"post_image": "https://localhost/800/400/cats/varem/?20215",
"post_description": "Omnis eius corporis incidunt illo dolor et est odio. Et fuga hic id. Velit voluptas tempore quas voluptas iusto. Quia rerum quibusdam consectetur distinctio vero. Nihil et sed reiciendis sequi. Possimus facere ducimus provident est. Qui ut rerum ab ullam sequi est. In placeat nesciunt odio numquam iure.",
"created_at": "2017-09-18T10:51:17.000000Z",
"likes": [
]
}
Output I want:
{
"post_id": 1,
"user_id": 3,
"post_image": "https://localhost/800/400/cats/varem/?20215",
"post_description": "Omnis eius corporis incidunt illo dolor et est odio. Et fuga hic id. Velit voluptas tempore quas voluptas iusto. Quia rerum quibusdam consectetur distinctio vero. Nihil et sed reiciendis sequi. Possimus facere ducimus provident est. Qui ut rerum ab ullam sequi est. In placeat nesciunt odio numquam iure.",
"created_at": "2017-09-18T10:51:17.000000Z",
"likes": [
"like_id": 3,
"user_id": 10,
"post_id": 1,
]
}
alihan.dev, You need to create Likes colletion and Likes api resoure and post reationship with Likes then following code will work for you :).
class Posts extends JsonResource {
//likes is relationship
public function toArray($request) {
return [
'group_id' => $this->group_id,
'u_t_id' => $this->u_t_id,
'group_by' => $this->group_by,
'likes' =>Likes::collection($this->likes),
];
}
}

How do I get the correct subnode with elasticsearch

I am trying to get specific parts of the data back from a specific document. The document contains product information. This is just a small snippet of the document to explain it better.
"_source": {
"product": {
"code": "AM109",
"stuff": "98989",
"languages": [
{
"language": "en",
"labels": {
"name": "Fusce nulla augue",
"description": "Cras ultricies diam vel orci feugiat ornare. Nulla convallis ligula quis fringilla suscipit. Proin malesuada ligula enim, sit amet semper lorem imperdiet in."
}
},
{
"language": "es",
"labels": {
"name": "Aliquam ut odio quam",
"description": "Nulla pulvinar tortor eu ex vestibulum, nec dictum diam tristique. Pellentesque vitae nibh diam. In id purus at sapien eleifend pulvinar non at velit."
}
}
}
}
The document contains different information for different countries, and labels for different languages. To explain I use the labels.
I need to get the information of the correct product based on the code (product.code), and for the languages it should already only return the labels in the language as requested. E.g. if language es is requested:
"_source": {
"product": {
"code": "AM109",
"stuff": "98989",
"languages": [
{
"language": "es",
"labels": {
"name": "Aliquam ut odio quam",
"description": "Nulla pulvinar tortor eu ex vestibulum, nec dictum diam tristique. Pellentesque vitae nibh diam. In id purus at sapien eleifend pulvinar non at velit."
}
}
}
}
I have tried this with nested options and filters, but I cannot get the correct data returned.
This is an existing system so I cannot make changes to the structure, but I can change the mapping if needed and repopulate the index.
Who can help me with this?
As all documents come with information about all languages and you only search in one language at a given time I suggest the following approach:
Store your documents in language specific indices (advantage: same field names)
You can send your documents always to the same index, but define an ingest pipeline which appends a language-specific suffix such as "_en" to your _index-field, to get your document routed/stored in the language-specific index
Adjust your query to only query the index containing the language
If the last step is not possible, you could define an alias, pointing to all language-specific indices and in your query filter on a field, containing the language-code

Laravel $user->notifications return null

I'm trying to get the notifications for a user. But when i the method get() in my NotificationController start it's always return null. This this the actual code i'm using to debug this feature :
function get(){
$user = \App\User::find(12);
dd($user->notifications);
}
The route is with POST method, i use Postman to test it. I always get error 500 with null content.
Do you know why ?
Thank's in advance
[EDIT]
This is the result of dd($user) for the get() method with POST request :
{
"id": 13,
"rang": 1,
"image": "https://www.drupal.org/files/profile_default.jpg",
"firstname": "Donald",
"lastname": "Torp",
"email": "ashlynn.mcclure#pacocha.com",
"created_at": null,
"updated_at": null
}
This is the content of my DB notifications table actually :
ID : e7f54269-a5ff-4109-9b8a-c2328fb6cf98
Type : App\Notifications\IdeaSelected
notifiable_type : App\Idea
notifiable_id : 13
data : {"idea":{"id":39,"name":"okeefe","description":"Sunt soluta et eum. Vitae sint adipisci et excepturi eos est exercitationem velit. Mollitia hic aut aperiam cum incidunt dolorem sed. Ut blanditiis eos temporibus hic illum quis.","image":"https:\/\/lorempixel.com\/400\/280\/?98265","user":13,"created_at":null,"updated_at":null}}
read_at :
created_at : 2018-04-14 00:57:37
Result for return (dd($user->load('notifications'))); :
#relations: array:1 [
"notifications" => DatabaseNotificationCollection {#549
#items: []
}
]
Result if i change the notifiable_type from App\Idea to App\User :
[
{
"id": "e7f54269-a5ff-4109-9b8a-c2328fb6cf98",
"type": "User::class",
"notifiable_type": "App\\User",
"notifiable_id": 13,
"data": {
"idea": {
"id": 39,
"name": "okeefe",
"description": "Sunt soluta et eum. Vitae sint adipisci et excepturi eos est exercitationem velit. Mollitia hic aut aperiam cum incidunt dolorem sed. Ut blanditiis eos temporibus hic illum quis.",
"image": "https://lorempixel.com/400/280/?98265",
"user": 13,
"created_at": null,
"updated_at": null
}
},
"read_at": null,
"created_at": "2018-04-14 00:57:37",
"updated_at": "2018-04-14 00:57:37"
}
]
Ah i see you are assigning the notifiable_type incorrectly it should say the User::class
When defining the notifiable model think to what you are sending an notification
You should be able to grab the notificationse once you store them in your database.
Take a look at the docs here https://laravel.com/docs/5.6/notifications#database-notifications

Searching for nested documents on a specific parent

In my Elasticsearch index, I have a book type that has many pages. Using nested documents, I have successfully mapped the relationship and I can index documents like this:
PUT /my_index/book/1
{
"title": "Harry Potter and the Chamber of Secrets",
"pages": [
{
"id": 1,
"text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam a metus est. Duis ut est et mi feugiat bibendum feugiat eu tortor. Pellentesque accumsan, eros nec commodo euismod, odio dolor lobortis diam, in pulvinar lacus turpis sed justo. Ut placerat ut nulla sed blandit. Aenean vel turpis erat. Phasellus vehicula laoreet ex, nec dapibus leo tempus vitae. Nulla gravida efficitur metus, in euismod justo placerat sit amet. Maecenas tristique est mauris, sagittis scelerisque turpis suscipit vel. Nullam ultricies sapien sit amet neque aliquam hendrerit sed non nibh."
},
{
"id": 2,
"text": "Pellentesque facilisis turpis in diam maximus luctus. Mauris leo diam, pellentesque a malesuada vitae, scelerisque at ipsum. Fusce tincidunt neque dui. Nullam ac ex luctus, convallis leo eget, feugiat augue. Cras condimentum, purus eu scelerisque sodales, diam est commodo lectus, at finibus orci turpis nec lectus. Mauris in lectus ut diam finibus pellentesque quis tincidunt urna. Curabitur tristique luctus metus at interdum. Curabitur imperdiet ex vel enim pretium, a convallis velit tempor. Nullam odio eros, tincidunt ut consectetur non, scelerisque eget urna. Fusce placerat dui et odio tempus rutrum. Integer non dui eu ante interdum volutpat. Mauris quis ante sed lacus euismod mattis."
}
]
}
I want to query and obtain all pages from a book which contain a certain word in the text field. I can do this like this:
POST /my_index/book/_search
{
"_source": false,
"query": {
"nested": {
"path": "pages",
"query": {
"query_string": {
"query": "Mundo",
"fields": ["pages.text"]
}
},
"inner_hits": {}
}
}
}
My problem however, is that I cannot find a way to specify which book I want to search in. Since I already know which book I'll be searching all pages from. I was trying to do this with a ids query, but I cannot find a way to use it with the nested query together.
How can I specify the book I want to search in (pages from this book), and make the response return a list of all the id values of each page? This id value is a reference to the page's page number in the book.
You can combine two conditions under Bool query like so:
{
"_source": false,
"query": {
"bool": {
"must": [
{
"term": {
"title": "Harry Potter and the Chamber of Secrets"
}
},
{
"nested": {
"path": "pages",
"query": {
"query_string": {
"query": "Mundo",
"fields": [
"pages.text"
]
}
},
"inner_hits": {
"_source": [
"pages.id"
]
}
}
}
]
}
}
}
As can be seen, I have encapsulate your nested query under bool-must (AND condition) and added term which defines the title to filter by.
Second thing, as you described you want only the pages-ids. So, under inner_hits I added "_source": ["id"] which gives you the ids only (it just the same trick
you did when you set the source off at the head of the query.
Pay attention, that, default size for inner_hits is 10, so you may also want to add "size": 1000 under inner_hits.
I will have another data model for your problem.
I will create two types:
A type book
A type Page
You will be able to create a parent/child relationship (The book being the parent and the page the child).
You will be able to make simple query on the page type then retrieve easily the parent of the page.

Resources