Show just the name of collection? - laravel

I have pivot table post_tag between posts and tags table.
I want to show the tags name for each post in resource API.
Resource file code snippets:
public function toArray($request)
{
return [
'Name'=> $this->title,
'Description'=> $this->desc,
'Image'=> $this->image_path,
'Posted By'=> $this->user->name,
'Category Name'=> $this->category->name,
'Tags' => $this->tags,
];
}
Relation added in Post model:
public function tags()
{
return $this->belongsToMany(Tag::class)->withTimestamps();
}
One of Results of an API:
"Name": "first post",
"Description": "desc of the post",
"Image": "https://blog.test/uploads/post/SjvDfC1Zk5UzGO6ViRbjUQTMocwCh0lzEYW1Gufp.jpeg",
"Posted By": "test",
"Category Name": "web dev",
"Tags": [
{
"id": 1,
"name": "HTML",
"created_at": "2020-01-08 19:19:55",
"updated_at": "2020-01-08 19:19:55",
"pivot": {
"post_id": 1,
"tag_id": 1,
"created_at": "2020-01-08 19:21:40",
"updated_at": "2020-01-08 19:21:40"
}
},
{
"id": 2,
"name": "CSS",
"created_at": "2020-01-08 19:19:55",
"updated_at": "2020-01-08 19:19:55",
"pivot": {
"post_id": 1,
"tag_id": 2,
"created_at": "2020-01-08 19:21:40",
"updated_at": "2020-01-08 19:21:40"
}
},
I need to show like that JUST names:
"Tags" : {
'HTML',
'CSS',
'JS',
}

You must be use like this
return [
'Name'=> $this->title,
'Description'=> $this->desc,
'Image'=> $this->image_path,
'Posted By'=> $this->user->name,
'Category Name'=> $this->category->name,
'Tags' => $this->tags->pluck('name')
];

Related

How to loop read all the column from the spreadsheet using Laravel-Excel

I have a spreadsheet that contains quiz records where I save all the quiz_questions and choices in the database.
I have this code reading and saving the spreadsheet but it has some issues, I want to save the choice_1, choice_2, choice_3, and choice_4 inside the database with the column name of choices. When I run this code it only save the choice_4 columns but not all of the choices. How can I get all the choices and save it? can anyone help me? thanks in advance.
This is my QuizImport
public function collection(Collection $rows)
{
foreach($rows as $row){
$quizQuestions = quizQuestions::create([
'quiz_id' => $row['quiz_id'],
'question_num' => $row['question_num'],
'question_content' => $row['question_content'],
'tagalog_question'=> $row['tagalog_question'],
]);
$quizQuestions->choices()->create([
'option' => $row['option_1'] || $row['option_2'] || $row['option_3'] || $row['option_4'],
'remarks' => $row['remarks_1'] || $row['remarks_2'] || $row['remarks_3'] || $row['remarks_4'],
'tagalog_choices'=> $row['tagalog_choices'],
]);
}
}
This is my controller
public function store(Request $request){
$file = $request->file('file');
Excel::import(new QuizImport, $file);
return response(['message'=>"Quiz successfully imported",
'error'=>false,
'error code'=>200,
'line'=>"line".__LINE__."".basename(__LINE__),
'file'=>$file],200,[],JSON_NUMERIC_CHECK);
}
This is the sample structure of my excel
This is the expected output
"quizQuestions": [
{
"id": 2,
"quiz_id": 6,
"question_num": 1,
"question_content": "<p>Sample Question</p>",
"correct_answer": null,
"created_by": 7,
"updated_by": null,
"created_at": "2021-09-06T07:27:20.000000Z",
"updated_at": "2021-10-18T17:35:17.000000Z",
"question_image": null,
"tagalog_question": "<p><span style=\"color: black;\">Tagalog Translation of the question</span></p>",
"choices": [
{
"id": 2,
"quiz_questions_id": 2,
"option": "choices_1",
"remarks": 1,
"created_at": "2021-09-06T07:27:48.000000Z",
"updated_at": "2021-10-18T17:53:13.000000Z",
"choices_image": null,
"tagalog_choices": "Tagalog"
},
{
"id": 3,
"quiz_questions_id": 2,
"option": "choices_2",
"remarks": 0,
"created_at": "2021-09-06T07:28:01.000000Z",
"updated_at": "2021-10-18T17:53:25.000000Z",
"choices_image": null,
"tagalog_choices": "Tagalog"
},
{
"id": 4,
"quiz_questions_id": 2,
"option": "choices_3",
"remarks": 0,
"created_at": "2021-09-06T07:28:54.000000Z",
"updated_at": "2021-10-18T17:53:32.000000Z",
"choices_image": null,
"tagalog_choices": "Tagalog"
},
{
"id": 5,
"quiz_questions_id": 2,
"option": "choices_4",
"remarks": 0,
"created_at": "2021-09-06T07:29:07.000000Z",
"updated_at": "2021-10-18T17:53:37.000000Z",
"choices_image": null,
"tagalog_choices": "Tagalog"
}
]
},
But this is what I get
"quizQuestions": [
{
"id": 541,
"quiz_id": 33,
"question_num": 1,
"question_content": "Sample Question",
"correct_answer": null,
"created_by": null,
"updated_by": null,
"created_at": "2022-01-10T11:35:42.000000Z",
"updated_at": "2022-01-10T11:35:42.000000Z",
"question_image": null,
"tagalog_question": "Tagalog Translation of the Question",
"choices": [
{
"id": 1735,
"quiz_questions_id": 541,
"option": "choice4",
"remarks": 0,
"created_at": "2022-01-10T11:35:42.000000Z",
"updated_at": "2022-01-10T11:35:42.000000Z",
"choices_image": null,
"tagalog_choices": "Tagalog"
}
]
},
I believe you need a loop for creating multiple choices with the same parent. (not tested)
public function collection(Collection $rows)
{
foreach($rows as $row){
$quizQuestions = quizQuestions::create([
'quiz_id' => $row['quiz_id'],
'question_num' => $row['question_num'],
'question_content' => $row['question_content'],
'tagalog_question'=> $row['tagalog_question'],
]);
for($i = 1; $i < 5; $++) {
$quizQuestions->choices()->create([
'option' => $row['option_' .$i],
'remarks' => $row['remarks_' . $i],
'tagalog_choices'=> $row['tagalog_choices'],
]);
}
}
}

Filter Data with Pivot Table Laravel Eloquent

I want to filter users based on their subscription_status which s stored in a pivot table.
I have Three tables users , subscription_packages , subscription_package_user
$user=User::with(['studentDetails','subscriptionsSatus.courses'])
->withPagination($offset,$perPage)
->get()
->sortBy('first_name')->values();
this code return the response is
[
{
"id": 44,
"first_name": "Abcd Test",
"last_name": "Test lastname",
"student_details": null,
"subscriptions_satus": [
{
"id": 1,
"name": "Gold",
"price": 3000,
"user_id": "2"
"pivot": {
"user_id": 44,
"subscription_package_id": 1,
"subscription_status": "on_free_trial",
"expires_on": null,
"id": 9
},
"courses": [
{
"id": 18,
"title": "English Grammar for Class 3",
"price": 400,
"strikethrough_price": null,
"status": "draft",
"user_id": 2,
"image": "http://127.0.0.1:8000/courses/1615702915.png",
"description": null,
"pivot": {
"subscription_package_id": 1,
"course_id": 18,
}
}
]
}
]
}]
i want to return only users who having subscription_status =$filter.
$filter='acive'or 'on_free_trail'
my model is
public function subscriptionsSatus()
{
return $this->belongsToMany(SubscriptionPackage::class)->withTimestamps()->withPivot('subscription_status','expires_on','id');
}
I havetried
$filter=$request->input('filter')??"active";
$user=User::with(['studentDetails','subscriptionsStatus.courses'])
->whereHas('subscriptionsStatus', function($query) use($filter){
$query->wherePivot('subscription_status','=',$filter);
})
->withPagination($offset,$perPage)
->get()
->sortBy('first_name')->values();
But Got error Column not found 'pivot'
You need to use wherePivot along with the orWhere like below:
public function subscriptionsStatus()
{
return $this->belongsToMany(SubscriptionPackage::class)
->withTimestamps()
->withPivot('subscription_status','expires_on','id')
->wherePivot(function($q){
return $q->where('subscription_status','=','active')
->orWhere('subscription_status','=','on_free_trail');
});
}
Update
Or in your controller:
$user=User::with(['studentDetails','subscriptionsStatus.courses'])
->whereHas('subscriptionsStatus', function($query) use($filter){
$query->withPivot('subscription_status')
->wherePivot('subscription_status','=',$filter);
})
->withPagination($offset,$perPage)
->get()
->sortBy('first_name')->values();

Retrieves the latest data from a foreign key in a relation

I want to ask, can I retrieve the last foreign key data in the relation ?.
In this case I want to retrieve the last user transaction data.
for example in the transaction table between 3 months ago and now there are some transaction data as follows.
{
"current_page": 1,
"data": [
{
"id": 8,
"user_id": 1,
"type": "sell",
"created_at": "2019-12-11 11:55:31",
"updated_at": "2019-12-11 11:55:31",
"tax": null,
"invoice_number": null,
"name": "Fredy"
},
{
"id": 7,
"user_id": 1,
"type": "buy",
"created_at": "2019-11-20 17:14:55",
"updated_at": "2019-11-20 17:14:55",
"tax": null,
"tax_percent": "0.90",
"invoice_number": null,
"name": "Fredy"
},
{
"id": 6,
"user_id": 8,
"type": "buy",
"created_at": "2019-11-20 16:28:33",
"updated_at": "2019-11-20 16:28:33",
"tax": null,
"name": "Tommy"
},
{
"id": 5,
"user_id": 2,
"type": "buy",
"created_at": "2019-11-20 15:47:57",
"updated_at": "2019-11-20 15:47:57",
"tax": null,
"name": "Sarah"
},
{
"id": 4,
"user_id": 3,
"type": "buy",
"created_at": "2019-11-20 15:47:31",
"updated_at": "2019-11-20 15:47:31",
"tax": null,
"name": "John Doe"
},
],
}
This is the sample code that i made
public function index()
{
$start = Carbon::now()->subMonths(3)->format('Y-m-d') . ' 00:00:00';
$end = Carbon::now()->format('Y-m-d') . ' 23:59:59';
return $query = DB::table('transaction')
->join('users', 'users.id', '=', 'gold_transaction.user_id')
->select('transaction.id', 'user_id', 'users.*')
->whereBetween('transaction.created_at', [$start, $end])
->whereIn('transaction.id', [DB::raw("SELECT MAX(transaction.id) FROM transaction GROUP BY user_id")])->get();
}
What do i do if i only want to display users who did't make transaction more than 7 days from the last transaction for all users ?
Thank you.
Then you can do it like below,
Get user's transaction
$transaction = User::with(['transactions' => function ($q) use($start, $end){
$q->whereBetween('transactions.created_at', [$start, $end]);
])->find($user_id);
Get all users with their transactions
$transaction = User::with(['transactions' => function ($q) use($start, $end){
$q->whereBetween('transactions.created_at', [$start, $end]);
])->get();
assuming that you have transactions relation in your user model like below
public function transactions() {
return $this->hasMany('App\Transaction', 'user_id');
}

How to map Laravel API resources for Non-Related Models

Hi I'm creating non related model resources. Inventories and Categories. They have child relationship models but they are not connected directly.
Sample:
{
"data": {
"inventories": [
{
"id": 1,
"user_id": 1,
"sub_category_id": 6,
"created_at": "2019-03-08 03:00:00",
"updated_at": "2019-03-08 03:00:00",
"deleted_at": null,
"get_inventory_details": {
"id": 1,
"inventory_id": 1,
"image_path": "Pahiram-Drone1-1.png",
"name": "Drone i1",
"description": "Drone i1 The Best Drone yet!",
"quantity": 10,
"cost_per_day": 1000,
"cost_per_hour": 100,
"status": "0",
"created_at": "2019-03-08 03:00:00",
"updated_at": "2019-03-08 03:00:00",
"deleted_at": null
}
}
],"categories": [
{
"id": 1,
"category_id": 1,
"parent_id": null,
"created_at": "2019-03-08 03:00:00",
"updated_at": "2019-03-08 03:00:00",
"deleted_at": null,
"get_sub_category_details": {
"id": 1,
"sub_category_id": 1,
"category_type_id": 1,
"name": "Drone DJI 1",
"description": "Drone DJI 1",
"created_at": "2019-03-08 03:34:23",
"updated_at": "2019-03-08 03:34:23",
"deleted_at": null
}
}
]
}
}
This is my sample data
It works with:
public function toArray($request)
{
return parent::toArray($request);
}
But not:
public function toArray($request)
{
return [
'inventory_ids' => $this->inventories->id,
'category_ids' => $this->categories->id
];
}
My expected result is to be able to map my response.
You Don't access direct id from categories and inventories, because its an array not object.
This should be usefull for you.
$categoryIds = Collection::make($this->categories)->pluck('id')->toArray();
$inventoryIds = Collection::make($this->inventories)->pluck('id')->toArray();
return [
'category_ids' => $categoryIds,
'inventory_ids' => $inventoryIds
];

How to join output of models in Laravel?

I have the following code:
$orders = OrderProduct::where(function ($query) use ($request) {
})->with('order_products')->orderBy('status', 'desc')->paginate(50)->toArray();
And order_products function is:
public function order_products()
{
return $this->hasMany("App\Order", "order_id", "order_id");
}
It gives me output result:
{
"user_id": "1",
"created_at": "2016-12-18 14:06:11",
"status": "2",
"note": "34535345",
"order_id": "2",
"address": "Kiev",
"courier_id": null,
"payment_type": "0",
"order_products": [
{
"id": 73,
"product_id": "1265",
"amount": "1"
},
{
"id": 74,
"product_id": "1266",
"amount": "1"
}
]
I need to join order_products with products_details, that to give title of product for each order like as:
"order_products": [
{
"id": 73,
"product_id": "1265",
"amount": "1",
"title": "Product name"
},
{
"id": 74,
"product_id": "1266",
"amount": "1",
"title": "Product name"
}
]
Instead this I get a new model output in response:
"products_details": [
{}, {}
]
How can I join two with models?
without joining, just using your first code:
in order_products, override the toArray() method.
function toArray() {
return [
id => $this->id,
product_id => $this->product_id,
amount => $this->amount,
title => $this->details->name
];
}
wich $this->details->name is the relation between order_products and products_details

Resources