Laravel resource: Get some of relations - laravel

There is a model User and a model Payments. I need to create a resource such that returns user with successful payment which is identified by a status fields. This is my solutions:
class User extends BaseModel
{
use HasFactory, SearchableTrait, SortableTrait;
protected $fillable = ['name', 'mobile', 'email', 'username', 'hash_id'];
public $searchable = ['name', 'mobile', 'email', 'id', 'user:referred'];
public $sortable = ['name', 'mobile', 'email', 'id'];
protected $table = 'users';
public function invoices()
{
return $this->hasMany(Invoice::class,'user_id');
}
}
and in controller
public function index()
{
$users = new User();
$users = $users::with(['invoices'])->filtered()->sorted();
return UserResource::collection($users->paginate());
}
and
<?php
namespace Modules\User\Transformers;
use Illuminate\Http\Resources\Json\JsonResource;
class UserResource extends JsonResource
{
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'mobile' => $this->mobile,
'invoices' => count($this->invoices()->where('status', 2999)->get()),
];
}
}
and model
class Invoice extends Model
{
protected $fillable = [];
protected $table = 'payment_invoices';
public function user()
{
return $this->belongsTo(User::class, 'user_id');
}
public function scopeSuccessful($query)
{
return $query->where('status', 2999);
}
}
It seems to be messy solution. I am looking for something to use the scope inside the model relation inside the resource. How can I do that?

in your controller you can just do this :
use Illuminate\Database\Eloquent\Builder;
public function index()
{
$users = User::with(['invoices'])->whereHas('invoices', function(Builder $query) {
$query->where('status', 2999);
});
return UserResource::collection($users->paginate());
}

<?php
class User extends BaseModel
{
use HasFactory, SearchableTrait, SortableTrait;
protected $fillable = ['name', 'mobile', 'email', 'username', 'hash_id'];
public $searchable = ['name', 'mobile', 'email', 'id', 'user:referred'];
public $sortable = ['name', 'mobile', 'email', 'id'];
protected $appends = ['success_payments']; // append this value in all queries
protected $table = 'users';
public function invoices()
{
return $this->hasMany(Invoice::class,'user_id');
}
//the function for it
public function getSuccessPaymentsAttribute(){
return App\Payment::where('user_id', $this->id)->where('status', 'success')->get(); //replace the attribute name or condition as per your db structure
}
}
You can use this in your User Model.

Related

multiple images not storing in database

I am trying to upload multiple images on database but its not storing. when I var_dump the data I see the images but it's not storing in database.
the code for store the data is---
$ad = AdList::create([
"userId" => $userId,
"adTitle" => $request->data['title'],
"photos" => json_encode($imageList),
]);
var_dump($ad);
And the I got after var_dump is---
["photos"]=>
string(51) "["dodo (1)_1668406861.webp","dodo_1668406862.webp"]"
what is the reason for not storing in database? I am using laravel & vue
Ad_list model---
class AdList extends Model
{
use HasFactory, Sluggable;
protected $guarded = [];
// public $incrementing = false;
// protected $table = 'ad_lists';
// protected $keyType = 'string';
public function user(){
return $this->belongsTo(User::class, 'userId','id');
}
public function category(){
return $this->belongsTo(Category::class, 'catId','id');
}
public function subcategory(){
return $this->belongsTo(Category::class, 'subCatId','id');
}
public function businessPage(){
return $this->belongsTo(BusinessPage::class, 'userId','userId');
}
/**
* Return the sluggable configuration array for this model.
*
* #return array
*/
public function sluggable(): array
{
return [
'url' => [
'source' => 'title'
]
];
}
}
Maybe your table is not connected to your model. Try to add this:
protected $table
class AdList extends Model
{
use HasFactory;
use Uuid;
public $incrementing = false;
protected $table = 'adlist_table';
protected $keyType = 'string';
protected $guarded = [];
}
Try to add protected $table = ''adlist_table" in your model;

Laravel Many-to-Many relationship not working

I'm facing a strange problem with Laravel Relations.
I'd like to access an event with many users (works perfect).
<?php
$event_with_user = Event::with('registered_users')->where('id', 253)->get();
dd($event_with_user);
And I'd like to access a user with all connected events:
<?php
$user_with_event = User::with('registered_events')->where('id', 1)->get();
dd($user_with_event);
Where I always receive this error:
Illuminate\Database\Eloquent\RelationNotFoundException
"Call to undefined relationship [registered_events] on model [App\User]."
I've checked the relations multiple times, but can't find a mistake. Does anyone else had that issue?
My Models
User.php
<?php
namespace App;
use App\Event;
use App\UserType;
use App\EventUser;
use App\Department;
use App\Evaluation;
use App\UserLocation;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'fname', 'lname', 'email', 'password', 'phone', 'email_verified_at', 'admin', 'user_type_id', 'last_login_at', 'last_login_ip', 'user_location_id', 'user_notification_type_id', 'user_notification_setting_id', 'slack_user_id', 'joinpoints_user_id'
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function registered_events()
{
return $this->belongsToMany(Event::class, 'event_user', 'event_id', 'user_id');
}
}
Event.php
<?php
namespace App;
use App\User;
use App\EventRoom;
use App\EventType;
use App\EventStatus;
use App\EventLocation;
use App\EventParticipant;
use App\EventParticipantItems;
use Illuminate\Database\Eloquent\Model;
use Cviebrock\EloquentSluggable\Sluggable;
class Event extends Model
{
use Sluggable;
protected $fillable = [
'event_type_id', 'user_id', 'status', 'customer', 'slug', 'datetime', 'duration','embed_chat','number_of_participants','heading', 'description_1', 'description_2', 'livestream_link', 'logo_link', 'event_password', 'participants_per_room', 'youtube_id', 'embed_code', 'session_link', 'hide_breakout', 'help_link', 'lang', 'layout', 'btn2_text', 'btn2_link', 'help_text', 'background_url', 'black_font',
];
protected $dates = ['datetime'];
public function getRouteKeyName()
{
return 'slug';
}
/**
* Return the sluggable configuration array for this model.
*
* #return array
*/
public function sluggable()
{
return [
'slug' => [
'source' => 'customer'
]
];
}
public function registered_users()
{
return $this->belongsToMany(User::class, 'event_user', 'user_id', 'event_id')->withPivot('id', 'user_status', 'eventmanager', 'created_at', 'updated_at');
}
}
My Tables:
user: id,....
event: id,...
event_user: id, user_id, event_id,...
Look a bit closer at your models :
return $this->belongsToMany(Event::class, 'event_user', 'event_id', 'user_id');
and
return $this->belongsToMany(User::class, 'event_user', 'event_id', 'user_id');
Whilst the table is right, you will need to swap the order of event_id and user_id on one of them...
Looks like you swapped the (foreign) keys:
In User.php:
public function registered_events()
{
return $this->belongsToMany(Event::class, 'event_user', 'user_id', 'event_id');
}
In Event.php:
public function registered_users()
{
return $this->belongsToMany(User::class, 'event_user', 'event_id', 'user_id')->withPivot('id', 'user_status', 'eventmanager', 'created_at', 'updated_at');
}
As you follow the correct Laravel database structure, you could simply put
return $this->belongsToMany(Event::class); in User.php and
return $this->belongsToMany(User::class)->withPivot(...); in Event.php

Return model relation / pivot in a method after creation in Laravel Eloquent

How can I return the model with his relation / pivot in a method after a firstOrNew?
Model:
class Customer extends Model
{
protected $table = 'customers';
protected $primaryKey = 'customer_id';
public $timestamps = true;
protected $fillable = [
'email',
'first_name',
'last_name',
'address',
'city',
'county',
'country',
'phone',
'organization_id',
'unique_value'
];
protected $guarded = [];
public function locations()
{
return $this->belongsToMany('App\Models\CustomerLocations', 'customer_customer_locations', 'customer_id', 'address_id')->withTimestamps();
}
}
Method:
$customer = Customer::firstOrNew(['unique_value' => $unique_code]);
Do some logic...
and
return $customer;
How can I return the $customer with locations()?? I will do a firstOrNew for locations too.
Use protected $appends = ['locations']; in your Model.
protected $primaryKey = 'customer_id';
public $timestamps = true;
protected $appends = ['locations'];
protected $fillable = [
'email',
'first_name',
'last_name',
'address',
'city',
'county',
'country',
'phone',
'organization_id',
'unique_value'
];
protected $guarded = [];
public function locations()
{
return $this->belongsToMany('App\Models\CustomerLocations', 'customer_customer_locations', 'customer_id', 'address_id')->withTimestamps();
}
Or you use return $cusotmer->load(['locations'])

Laravel adding details of two different user into there respected table

I want to store details as per user who is login and there ROLE that is whether they are teacher or student in respected table
In my Controller
public function store(Request $request)
{
$input = Request::all();
$this->validate($request,[
'user_id'=>'required',
'city'=>'required',
]);
if (User::find($role,'teacher')){
Teacher::create($input);
}
else{
Student::create($input);
}
return redirect ('home');
}
Now my Model for users
protected $fillable = [
'name', 'email', 'password','role'
];
protected $hidden = [
'password', 'remember_token',
];
public function details()
{
return $this->hasOne(['App\Teacher','App\Student']);
}
teachers model
protected $fillable = [
'user_id', 'city',
];
public function user()
{
return $this->belongsTo('App\User');
}
now students model
protected $fillable = [
'user_id', 'city',
];
public function user()
{
return $this->belongsTo('App\User');
}

Laravel eloquent add extra models to hasMany

I have a user Model and each user has multiple licenses. There are 2 default licenses that apply to all users that are not in the licenses table and they need to be created on the fly using certain data contained in the User model.
How can I create 2 licenses each time I'm getting a user's licenses and add it to the output of licenses()?
class User extends Model implements AuthenticatableContract, CanResetPasswordContract {
use Authenticatable, CanResetPassword;
protected $table = 'users';
public $timestamps = false;
protected $fillable = ['name', 'email', 'password'];
protected $hidden = ['password', 'remember_token'];
public function licenses()
{
return $this->hasMany('App\License', 'user_id', 'id')->where('deleted', '=', '0');
}
}
You could create an extra function in the model where you call the licenses and add the extra licenses.
Remember to test all places where you use this function so no strange stuff will happen.
<?php
class User extends Model implements AuthenticatableContract, CanResetPasswordContract {
use Authenticatable, CanResetPassword;
protected $table = 'users';
public $timestamps = false;
protected $fillable = ['name', 'email', 'password'];
protected $hidden = ['password', 'remember_token'];
// HasMany function
public function _licenses()
{
return $this->hasMany('App\License', 'user_id', 'id')->where('deleted', '=', '0');
}
// New licenses function
public function licenses()
{
// Get licenses from database
$licenses = $this->_licenses;
// Add other lisences
$licenses = $licenses->add(new License([ "user_id" => $this->id, "name" => "foo" ]));
$licenses = $licenses->add(new License([ "user_id" => $this->id, "name" => "bar" ]));
// Return the new collection
return $licenses
}
}

Resources