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;
Related
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",
}
`````
I'm trying to add an extra field to my Laravel 7 API model:
class Layer extends Model {
protected $fillable = ['name', 'filename', 'status', 'category_id'];
protected $appends = ['category_name'];
public function getCategoryNameAttribute()
{
return $this->category->name;
}
public function category()
{
return $this->belongsTo('App\LayerCategory', 'category_id');
}
}
My Controller:
.....
public function index()
{
return Layer::orderBy('name', 'asc')->paginate();
}
.....
I expect the following response:
{
"id": 1,
"category_id": 1,
"name": "My Layer",
"filename": "file_name.zip",
"status": true,
"category_name": "My category name"
}
But I receive:
{
"id": 1,
"category_id": 1,
"name": "My Layer",
"filename": "file_name.zip",
"status": true,
"category_name": "My category name",
"category": [
"id": 1,
"name": "My category name",
"status": true
]
}
How to return only the category name?
PS: I also tried with Resources.
Since you're eager loading the Category relationship to get category_name, you'll need to add logic to hide category from your JSON response. This can be done using the Hidden attribute on Serialization:
protected $hidden = ['category'];
You can read https://laravel.com/docs/7.x/eloquent-serialization#hiding-attributes-from-json for more information.
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();
}
I am new in Laravel,
I want to pass the the $id from my controller in the model using with clause
My model
class Menucategory extends Model
{
protected $fillable = ['title', 'parent_id', 'restaurant_id'];
// loads only direct children - 1 level
public function children()
{
return $this->hasMany('App\Menucategory', 'parent_id');
}
// recursive, loads all descendants
public function childrenRecursive()
{
return $this->children()->with('childrenRecursive');
}
}
My Controller
public function show($id)
{
$menucatagories = Menucategory::with('childrenRecursive')->where('restaurant_id',$id)->where('parent_id','0')->get();
return $menucatagories;
}
My current output is
[
{
"id": 1,
"title": "TestMenu Parant",
"parent_id": 0,
"restaurant_id": 12,
"children_recursive": [
{
"id": 2,
"title": "TestMenu SubCat1",
"parent_id": 1,
"restaurant_id": 12,
"children_recursive": [
{
"id": 6,
"title": "TestMenu other sub cat",
"parent_id": 2,
*******************
"restaurant_id": 13,
*******************
"children_recursive": []
},
{
"id": 7,
"title": "TestMenu other sub cat",
"parent_id": 2,
"restaurant_id": 12,
"children_recursive": []
}
]
},
{
"id": 3,
"title": "TestMenu SubCat2",
"parent_id": 1,
"restaurant_id": 12,
"children_recursive": []
}
]
}
]
I passed $id=12 , but the problem is I get the values of others restaurant_id in my child array, but if i use this it shows the correct jSON
public function childrenRecursive()
{
$id=12;
return $this->children()->with('childrenRecursive')->where('restaurant_id',$id);
}
my questions is how can i pass the $id from the controller to the model or is there any other approach?
You can pass your parameter in the controller itself using the following way.
public function show($id)
{
$menucatagories =Menucategory::with(array('childrenRecursive'=>function($query) use ($id){
$query->select()->where('restaurant_id',$id);
}))
->where('restaurant_id',$id)->where('parent_id','0')->get();
return $menucatagories;
}
Your childrenRecursive isn't wrong at all.
See here an simliar example: https://stackoverflow.com/a/18600698/2160816
So I think this should work
public function childrenRecursive($id = 12){
return $this->children()->where('restaurant_id',$id)->with('childrenRecursive');
}
Your Controller then could call
public function show($id)
{
$menucatagories = Menucategory::where('parent_id','0')->childrenRecursive(12)->get();
return $menucatagories;
}
I could not test it so may it won't work 100%
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() );