eloquent sum of relation's column in single query - laravel

in this query i have three table such as radio, radio_channels and radio_channels_files which into that i want to calculate one column which that is into radio_channels_files table as new column such as duration_sum, my below code work but i can't calculate this column
class Radio extends Model
{
use SoftDeletes;
protected $guarded = ['id'];
protected $casts = [
'logo_path' => 'array',
'cover_path' => 'array'
];
public function category()
{
return $this->belongsTo(RadioCategory::class);
}
public function channels()
{
return $this->hasMany(RadioChannels::class);
}
}
class RadioChannelsFiles extends Model
{
protected $guarded = ['id'];
protected $casts = [
'image' => 'array',
//'keywords' => 'array',
];
public function channel()
{
return $this->belongsTo(RadioChannels::class,'playlist_id');
}
}
class RadioChannels extends Model
{
protected $guarded = ['id'];
protected $casts = [
'image' => 'array'
];
public function channel()
{
return $this->belongsTo(Radio::class);
}
public function files()
{
return $this->hasMany(RadioChannelsFiles::class , 'playlist_id');
}
public function duration_sum()
{
return $this->hasOne(RadioChannelsFiles::class ,'playlist_id')
->select('duration',
DB::raw('sum(duration)')
)->groupBy('duration');
}
}
$channels = Radio::with(['category', 'channels' => function ($query) {
$query->with(['files','duration_sum']);
}])->paginate(50);
i get null output:
#relations: array:2 [▼
"files" => Illuminate\Database\Eloquent\Collection {#1422 ▶}
"duration_sum" => null //should return sum of duration from files
]

i figured out how can i get it
public function getRadiosList(Request $request)
{
$radios = Radio::with(['category', 'playLists' => function ($query) {
$query->with(['files','duration_sum']);
}])->get();
return response()->json(['data' => $radios, 'statusCode' => 1], 200);
}
model:
public function duration_sum()
{
return $this->hasOne(RadioPlaylistsFiles::class, 'playlist_id')
->select('playlist_id',
DB::raw('sum(duration) as `all_duration`')
)->groupBy('playlist_id');
}

Related

Astrotomic Translatable - pivot column - Laravel 9

I'm having trouble translating a pivot column.
I've been trying all day to add this translation but it still doesn't work.
I'm using the package: https://github.com/Astrotomic/laravel-translatable
Plain tables work fine, but pivot doesn't.
My code (the naming was quick, as the code will work, I'm going to refactor it):
class Offer extends Model implements TranslatableContract
use HasFactory, Translatable;
public array $translatedAttributes = [
'name',
'description'
];
public function attributes(): BelongsToMany
{
return $this->belongsToMany(Attribute::class, 'attribute_offer')->using(AttributeOffer::class)->withTimestamps();
}
class Attribute extends Model implements TranslatableContract
{
use HasFactory, Translatable;
public array $translatedAttributes = [
'name',
];
public function values(): BelongsToMany
{
return $this->belongsToMany(Offer::class, 'attribute_offer', 'attribute_id', 'offer_id')->using(AttributeOffer::class);
}
class AttributeOffer extends Pivot implements TranslatableContract
{
use Translatable;
public $incrementing = true;
public array $translatedAttributes = [
'content',
];
protected $fillable = [
'attribute_id',
'offer_id',
];
}
class AttributeOfferTranslation extends Model
{
protected $table = 'attribute_offer_translations';
public $timestamps = false;
protected $fillable = [
'content',
];
}
class OfferController extends Controller
{
private function updateAttributeValues($offer, $attributes)
{
foreach ($attributes as $slug => $values) {
$pivot = $offer->attributes()->whereSlug($slug)->first()->pivot;
foreach ($values as $locale => $value) {
$pivot->translate($locale)->content = $value;
}
}
}
The structure of the attributes is:
[
'test' =>[
'en' => 'test',
'es' => 'test',
'de' => 'test',
],
'test2' =>[
'en'=> 'test',
'es'=> 'test',
'de' => 'test',
],
]
Unfortunately pivot->translate() always returns null.
Also, when I manually add transactions to the database, it does not display it.
I will be very grateful for help with this translation.
Okay, I fixed it like this, only I have to pass id instead of slugs.
class Offer extends Model implements TranslatableContract
{
...
public function attributeValues(): HasMany
{
return $this->hasMany(AttributeOffer::class);
}
}
class AttributeOffer extends Pivot implements TranslatableContract
{
...
protected $translationForeignKey = 'attribute_offer_id';
...
}
private function updateAttributeValues($offer, $attributes)
{
foreach ($attributes as $id => $values) {
$offer->attributeValues()->whereAttributeId($id)->first()->update($values);
}
}

Relationship between pivot tables - return resource do not found using pivot or belongsToMany

good afternoon!
I would like some help from them regarding the scenario below:
I have 3 tables, 1 is the Moviment which is the main one, the 2 is the cart_moviments which is the secondary one which when I enter the movement data, it saves some data in cart_moviments and I have the 3 table called vehicles, which I have all the vehicle information, all of them have a foreignId, just to relate them.
So on my return from the resource, I have Moviment->cartMoviment, and I want to access it from cartMoviment ->vehicles, which I can't, because it doesn't relate.
My code Store:
public function store(StoreMovimentRequest $request, StoreCartMovimentRequest $requestCart, StoreDocumentRequest $requestDocument)
{
$this->authorize('create', Moviment::class);
$moviment = Moviment::create($request->validated());
$moviment->cartMoviment()->create($request->validated());
foreach(array($request['key_number']) as $notasFiscais) {
foreach($notasFiscais as $notas) {
$moviment->document()->create($notas);
}
}
return new MovimentResource($moviment);
}
My CartMoviment MOdel:
class CartMoviment extends Model
{
use HasApiTokens, HasFactory, Notifiable, UserTenant;
protected $fillable = ['type', 'vehicle_cart_id'];
// protected $table = 'cart_moviments';
public function Moviment() {
return $this->belongsTo(Moviment::class);
}
public function Vehicle() {
return $this->belongsTo(Vehicle::class, 'vehicle_cart_id');
}
My Moviment Model:
class Moviment extends Model
{
use HasApiTokens, HasFactory, Notifiable, UserTenant;
protected $fillable = [
'document_type_id', 'people_id', 'company_id', 'vehicle_id', 'department_id'
];
public function Vehicle() {
return $this->belongsTo(Vehicle::class);
}
public function cartMoviment() {
return $this->belongsToMany(Moviment::class, cartMoviment::class);
}
`
My resource Array:
public function toArray($request)
{
return [
'id' => $this->id,
// 'count' => $this->count(),
'type' => $this->type,
'department_id' => $this->department_id,
'person_id' => $this->people_id,
'person_name' => $this->person->name,
'vehicle_id' => $this->vehicle_id,
'vehicle_board' => $this->vehicle->board,
'vehicle_status' => $this->vehicle->status,
'vehicle_manufacturer' => $this->vehicle->vehicleModel->name,
'vehicle_type' => $this->vehicle->vehicleType->type,
'cart_moviment' => $this->cartMoviment,
My return resource
"cart_moviment": [
],
"documents": [
],
`
I need relationship , thanks you very match.

Laravel 8: Undefined index

I'm working on a questionnaire project and I ran into an error saying:
Undefined index: exams
This happened when I was trying to store responses to my database.
Here is my controller code:
public function store(Math $math)
{
$data = request()->validate([
'responses.*.answer_id' => 'required',
'responses.*.question_id' => 'required'
]);
$exam = $math->exams()->create($data['exams']);
$exam->examanswers()->createMany($data['examanswers']);
return 'Thank You';
}
Here is my exam model:
{
use HasFactory;
protected $fillable = ['exam'];
public function math()
{
return $this->belongsTo(Math::class);
}
public function examanswers()
{
return $this->hasMany(ExamAnswer::class);
}
}
question model:
{
use HasFactory;
protected $fillable = ['question'];
public function math()
{
return $this->belongsTo(Math::class);
}
public function answers()
{
return $this->hasMany(Answer::class);
}
}
Math model:
{
use HasFactory;
protected $fillable = [
'user_id', 'title', 'purpose', 'exam'
];
public function user()
{
return $this->belongsTo(User::class);
}
public function questions()
{
return $this->hasMany(Question::class);
}
public function exams()
{
return $this->hasMany(Exam::class);
}
}
Please help me look into it.
request()->validate(RULES) will return an array with all the existing rules' indexes. It will not return all data present, just what it is in the rules and present.
Read how $request->validate() works.
For example:
If you send home = 'Address', name = 'John' and email = 123, but your rules are:
$data = $request->validate([
'home' => 'required',
'name' => 'required',
]);
Then, if you want to use $data you would have (dd($data)):
$data['home']: Address
$data['name']: John
But email = 123 would not be present in $data.

Laravel Algolia Scout, whereIn on relationships

I am working on a Laravel project. I am using Scout based on Algolia. But I struggling to apply whereIn on the relationships. I have 2 models as follow.
Place.php
class Place extends Model
{
use Searchable, Localizable;
protected $with = [
'images',
'phones',
'emails',
'categories'
];
protected $casts = [
'is_featured' => 'boolean'
];
public function categories()
{
return $this->belongsToMany(Category::class, 'place_category');
}
public function searchableAs()
{
return "places_index";
}
public function toSearchableArray()
{
$record = $this->toArray();
$record['_geoloc'] = [
'lat' => $record['latitude'],
'lng' => $record['longitude'],
];
$record['categories'] = $this->categories->map(function ($data) {
return [
'id' => $data['id'],
'en_name' => $data['en_name'],
'mm_name' => $data['mm_name'],
];
})->toArray();
unset($record['created_at'], $record['updated_at'], $record['latitude'], $record['longitude']);
unset($record['images'], $record['phones'], $record['emails']);
return $record;
}
}
Category.php
class Category extends Model
{
use Searchable;
protected $touches = [
'places',
];
public function places()
{
return $this->belongsToMany(Place::class, 'place_category');
}
}
Now, I am searching the Place models/ data filtering by category. As you can see, I have also indexed the categories with places in toSearchableArray method.
I am trying to achieve something like this.
Place::search($keyword)->whereIn('categories', ????);//how can I filter by the Ids here
How can I do that?

Laravel eloquent: Multiply two columns of two different tables

My Order Model
class Order extends Model
{
protected $fillable = [
'id','user_id', 'erp_id', 'currency_code','ex_rate_with_base','order_status','status','created_at'
];
protected $hidden = ['updated_at',];
public function orderList(){
return $this->hasMany(OrderList::class);
}
public function currency(){
return $this->belongsTo(Currency::class,'currency_code');
}
}
My Currency Model
class Currency extends Model
{
protected $fillable = [
'currency_code','currency_name', 'currency_symbol', 'ex_rate_with_base', 'update_via', 'status',
];
protected $hidden = [
'created_at','updated_at','updated_by','created_by',
];
protected $primaryKey = 'currency_code';
public $incrementing = false;
public function order()
{
return $this->hasMany(Order::class,'currency_code');
}
}
My OrderList Model
class OrderList extends Model
{
protected $fillable = [
'id','order_id', 'product_code', 'qty','unit_price','status',
];
protected $hidden = [
'created_at' ,'updated_at',
];
public function order(){
return $this->belongsTo(Order::class);
}
}
In my Order controller I want to run the query:
$order_history_list = Order::where([['user_id', $user->id], ['updated_at','>', $updated_at]])
->with([
'currency' => function ($query) {
$query->select('currency_code','currency_symbol','ex_rate_with_base');
},
'orderList' => function ($query) {
$query->select('id','order_id', 'product_code', '***order_lists.qty * orders.ex_rate_with_base AS unit_price_with_ex_rate***','status');
}
])->get();
But error is occuring due to the highlighted portion.
Error: Unknown column 'order_lists.qty * orders.ex_rate_with_base' in 'field list'
Please help me with the correct syntax
How can I use column of order table in the sub query ?
Use DB::raw in your select statement and add a join to the 'orderList' $query
$order_history_list = Order::where([['user_id', $user->id], ['updated_at','>', $updated_at]])
->with([
'currency' => function ($query) {
$query->select('currency_code','currency_symbol','ex_rate_with_base');
},
'orderList' => function ($query) {
$query->select('id','order_id', 'product_code', DB::raw('order_lists.qty * orders.ex_rate_with_base AS unit_price_with_ex_rate'),'status')
->join('orders','order_lists.order_id', 'orders.id');
}
])->get();
My Final Query That Worked:
$order_history_list = Order::where([['user_id',$user->id],['updated_at','>',$updated_at]])
->with(['currency'=>function($query){
$query->select('currency_code','currency_symbol','ex_rate_with_base');
},'orderList' => function($query){
$query->select('order_lists.id','order_lists.order_id', 'order_lists.product_code', 'order_lists.qty','order_lists.unit_price',DB::raw('he_order_lists.qty* he_orders.ex_rate_with_base AS unit_price_with_ex_rate'),'order_lists.status')->join('orders','order_lists.order_id', 'orders.id');
}])->get();

Resources