Rename relation name when auto fetching in eloquent - php

class Order extends Elequent{
protected $table = 'order';
const CREATED_AT = "createdAt";
const UPDATED_AT = "updatedAt";
protected $with = array('orderItem', 'address');
public function orderItem(){
return $this->hasMany("OrderItem","orderId");
}
public function address(){
return $this->hasOne("OrderAddress","orderId","id");
}
}
//in controller
$order = Order::findOrFail($orderId);
echo $order;
When serialize the order to json using above class,how can I make the order_item to orderItem(I like camel case more than snake case)
{
"id": 1,
"userId": 1,
"createdAt": "2015-04-30 12:08:26",
"deletedAt": "0000-00-00 00:00:00",
"updatedAt": "2015-04-30 12:08:26",
"state": "activated",
"deliveryNote": null,
"order_item": [
{
"id": 1,
"specialProductId": 29,
"volume": 750,
"quantity": 2,
"price": "543.38",
"orderId": 1,
"updatedAt": "2015-04-30 12:08:26",
"createdAt": "2015-04-30 12:08:26"
}
],
"address": null
}

In your model, set the $snakeAttributes property to false. This will keep the attributes from being snake_cased when generating the array.
class Order extends Elequent {
public static $snakeAttributes = false;
}

You can copy/rename the object property and unset the old one.
//in controller
$order = Order::findOrFail($orderId);
$order->orderItem = $order->order_item;
unset($order->order_item);
echo $order;
For better usage, you can put this method on your Base model,
public function toArrayCamel()
{
$array = $this->toArray();
foreach($array as $key => $value)
{
$return[camel_case($key)] = $value;
}
return $return;
}
and later on your controller,
$order = Order::findOrFail($orderId);
return Response::json( $order->toArrayCamel() );

Related

i need return many ids from relationship in model

need return many ids from relationship in model
I need help fetching the data for these ids from another table. Now it saves the multiple ids, but when querying, the response appears only individually. Please, I want to show all returns of ids
my Controller
<?php
namespace App\Http\Controllers\Api;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Requests\BookingRequest;
use App\Http\Resources\BookingResource;
use App\Models\Booking;
use App\Models\Installment;
class BookingController extends Controller
{
public function store(Request $request, Booking $booking)
{
$booking = Booking::create($request->only([
'patient_id',
'setting_id',
'procedure_id',
'procedure_ids',
]));
return new BookingResource($booking);
}
}
my Model
In the model I added the relationship between the columns and the fetch works perfectly, but for one result I want to return with all the results
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Booking extends Model
{
use \EloquentFilter\Filterable;
protected $table = 'bookings';
protected $keyType = 'integer';
protected $casts = [
'procedure_ids' => 'array',
];
protected $fillable = ['setting_id', 'procedure_id','procedure_ids'];
public function patient()
{
return $this->belongsTo('App\Models\Patient');
}
public function procedure()
{
return $this->belongsTo('App\Models\Setting', 'procedure_id');
}
public function procedures()
{
return $this->belongsTo('App\Models\Setting', 'procedure_ids');
}
public function setting()
{
return $this->belongsTo('App\Models\Setting');
}
public function installments()
{
return $this->hasMany('App\Models\Installment');
}
}
my Request
Added in the request * with the last parameter to receive multiple ids
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class BookingRequest extends FormRequest
{
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
// check if update request or store request
$id = $this->booking->id ?? "NULL";
return [
'procedure_ids.*' => ['required_if:type,==,procedure', 'array', 'exists:settings,id'],
];
}
}
i need my results to be
{
"data": {
"patient_id": "3",
"setting_id": "572",
"procedure_id": "580",
"procedure_ids": [
"680",
"679",
"678"
],
"date": "2021-06-08",
"time": "20:59",
"total": "500",
"unpaid": "0",
"id": 123,
"procedures": [
"680" {
"id": 680,
"type": "procedure_typs",
"title": "Surgery"
},
"681" {
"id": 681,
"type": "procedure_typs",
"title": "codo"
}]
}
not
"data": {
"patient_id": "3",
"setting_id": "572",
"procedure_id": "580",
"procedure_ids": [
"680",
"679",
"678"
],
"date": "2021-06-08",
"time": "20:59",
"total": "500",
"unpaid": "0",
"id": 123,
"procedures": {
"id": 680,
"type": "procedure_typs",
"title": "Surgery",
}
`````

Group Laravel Eloquent pivot values by id

I have a relational database whose models look like this:
Restaurant:
class Restaurant extends Authenticatable
{
public function dishes()
{
// return $this->hasMany(Dish::class);
return $this->belongsToMany('App\Models\Dish');
}
}
Dish:
class Dish extends Model
{
public function orders()
{
return $this->belongsToMany('App\Models\Order')->withPivot('quantity');
}
public function restaurant()
{
return $this->belongsToMany('App\Models\Restaurant');
}
}
Order
class Order extends Model
{
public function dishes()
{
return $this->belongsToMany('App\Models\Dish');
}
}
I'm retrieving all orders belonging to the restaurant by id like so:
public function index($id)
{
$user_id = $id;
$dishes = Dish::where('restaurant_id', $user_id)->get();
foreach ($dishes as $dish => $value) {
$orders = $value->orders;
foreach ($orders as $order => $value) {
$response[] = $value;
}
}
return response()->json($response);
}
This works, but I would like to group these results by order_id in some way, so that I get returned something similar to this:
{
"id": 28,
"status": 1,
"address": "Fish Street",
"user_name": "Artyom",
"user_surname": "Pyotrovich",
"phone": "351 351 643 52",
"email": "artyom#restaurant.com",
"total": 35.8,
"created_at": "2021-11-17T10:44:58.000000Z",
"updated_at": "2021-11-17T10:44:58.000000Z",
"dishes": [{
"dish_id": 22,
"quantity": 3
},
{
"dish_id": 23,
"quantity": 1
}]
}
Is this possible by simply changing the Eloquent query or do I need to perform several operations on the result of my current query? Also interested in what is actually the best practice in these cases.
Thanks in advance
You can use the ::with() method to get all the desired relations, this is much cleaner then a foreach rewrite.
Example:
$orders = Order::with('dishes')
->whereHas('dishes', function(Builder $dishes) use ($user_id) {
$dishes->where('restaurant_id', $user_id);
})->get();
return response()->json( $order );
Small note:
Separate the user id from the restaurant id, what if the user has multiple restaurants?

Best way to save/update data from json to Laravel model with relationships

I have two models:
Models/Arrival.php:
protected $guarded = [];
public function nomenclatures()
{
return $this->hasMany(ArrivalNomenclature::class, 'arrival_id', 'id');
}
public function warehouses()
{
return $this->belongsTo(Warehouse::class, 'warehouse_id', 'id');
}
Models/ArrivalNomenclatures.php:
protected $guarded = ['id'];
public function nomenclatures()
{
return $this->belongsTo(Nomenclature::class, 'nomenclature_id');
}
public function arrivals()
{
return $this->belongsTo(Arrival::class, 'arrival_id');
}
I need to save from json:
{
"type": "provider",
"invoice": "123yk43",
"filial_id": 10,
"warehouse_id": 6,
"provider_id": 9,
"responsible": "ttt",
"user_id": "4",
"carried_out": 0,
"nomenclatures": [
{
"confirmed": 0,
"nomenclature_id": 1,
"price": 1337,
"quantity": 10,
},
{
"confirmed": 0,
"nomenclature_id": 1,
"price": 1337,
"quantity": 10,
}
....
]}
Creation raises no questions.
How to update models correctly?
$arrival = Arrival::findOrFail($id);
$arrival->update($dataArrival);
ArrivalNomenclature::where('arrival_id', $arrival->id)->delete();
foreach ($request->nomenclatures as $nomenclature) {
$data[] = new ArrivalNomenclature($nomenclature);
}
$arrival->nomenclatures()->saveMany($data);
At the moment I find it by id and make an update. Then I delete all child records by id. I create an array of models in a loop and use the saveMany () method to save it to the database.
Is there a nicer way?

Load All posts with their tags into an array Laravel eloquent polymorphic relationship

I need to fetch all posts existed in my table with all their tags into an array. As you see below, this query just gets the posts that have tags but I need all posts even they don't have any tags. In addition, I need to have a tag:[] variable in my array but I don't know how to get all posts with their tags in one query.
Thank you in advance.
public function getItemsWithTags(array $attr)
{
return self::$model::
whereNotNull('title')->
whereNotNull('content')->
whereNotNull('author')->
whereNotNull('category')->
whereNotNull('img_url')->
has('tags')->
get()->
toArray();
}
class BaseModel extends Model
{
protected $table;
protected $primaryKey;
use SoftDeletes;
}
class BlogModel extends BaseModel
{
protected $table = 'blog';
protected $primaryKey = 'id';
public function tags()
{
return $this->morphToMany(TagsModel::class,'taggable',null,null,'tag_id');
}
}
class TagsModel extends BaseModel
{
protected $table = 'tags';
protected $primaryKey = 'id';
protected $fillable = ['name'];
public function blog()
{
return $this->morphedByMany(BlogModel::class,"taggable");
}
}
the Output of this query:
{
"id": 28,
"title": "dfg",
"content": "<ul>\n<li>rdgrdgf</li>\n<li>dfg</li>\n<li>dg</li>\n<li>dgf</li>\n<li>dfg</li>\n</ul>",
"author": "gd",
"category": "Design",
"img_url": "uploads/post/Screenshot from 2020-03-27 20-34-42_7dc41dca1ebc4dabcb921fc7f4c4744a.png",
"created_at": "2020-05-03T18:47:38.000000Z",
"updated_at": "2020-05-03T18:47:38.000000Z",
"deleted_at": null,
"user_id": 1,
"category_id": 7
}
and what I need is :
{
"id": 28,
"title": "dfg",
"content": "<ul>\n<li>rdgrdgf</li>\n<li>dfg</li>\n<li>dg</li>\n<li>dgf</li>\n<li>dfg</li>\n</ul>",
"author": "gd",
"category": "Design",
"img_url": "uploads/post/Screenshot from 2020-03-27 20-34-42_7dc41dca1ebc4dabcb921fc7f4c4744a.png",
"created_at": "2020-05-03T18:47:38.000000Z",
"updated_at": "2020-05-03T18:47:38.000000Z",
"deleted_at": null,
"user_id": 1,
"category_id": 7,
"tags":['tag1','tag2']
}
return self::$model::
with('tags')->
whereNotNull('title')->
whereNotNull('content')->
whereNotNull('author')->
whereNotNull('category')->
whereNotNull('img_url')->
get()->
toArray();
You use has as the name tells, this method checks if there is a tag relationship, use with instead:
public function getItemsWithTags(array $attr)
{
return self::$model::
whereNotNull('title')->
whereNotNull('content')->
whereNotNull('author')->
whereNotNull('category')->
whereNotNull('img_url')->
with('tags')->
get()->
toArray();
}

Laravel/Eloquent mutate model on join

I'm trying to mutate a model to display an array of strings and not an array of objects.
Current Output
{
"id": 1,
"company_name": "blah"
"language": [
{
"name": "English"
},
{
"name": "French"
}
]
},
{
"id": 2,
"company_name": "blah2"
"language": [
{
"name": "English"
},
{
"name": "French"
}
]
}
Desired Output
{
"id": 1,
"company_name": "blah"
"language": ["English","French"]
},
{
"id": 2,
"company_name": "blah2"
"language": ["English","French"]
}
Partner Model
class Partner extends Eloquent
{
protected $table = 'property_managers';
protected $visible = array('id','company_name','language');
public function language(){
return $this->belongsToMany('Language', 'property_manager_language', 'property_manager_id', 'language_id');
}
}
Language Model
class Language extends Eloquent
{
protected $table = 'languages';
protected $visible = array('name');
public function propertyManager()
{
return $this->belongsToMany('PropertyManager');
}
}
I'm accessing it via the code snippet below
$pm = Partner::with('language')->get();
I looked into mutators but it doesn't seem to hit that attribute within the partner model.
public function getLanguageAttribute(){
//run my code to flatten to array
}
So I'm curious as to if mutators don't work on joins or how you would be able to modify the return on the join. I can add a mutator to the Language model but that will only modify the attributes of that specific model. Any insight would be helpful. Thanks
In your model,
public function getLanguagesAttribute(){
return array_pluck(collect($this->language)->toArray(), 'name');
}
luego prueba con esto
$partner = Partner::find(1);
return $partner->languages;

Categories