Laravel eloquent add extra models to hasMany - laravel

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
}
}

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;

Round robin not functioning well

I try to create a function using round robin where all user in a group will be moderator for every meeting created.For example, a group have 2 users, I managed to create the first two meeting with the two users, but when I created the third meeting, it become null.
public function addsession(Request $req)
{
$mod = null;
$latestUserId=Meeting::where('groupID', $req->groupID)
->latest('id')
->first()
?->meetingModerator;
//the first meeting or all the users have already had their turn
$firstUserId=DB::table('group_user')
->where('group_id', $req->groupID)
->orderBy('user_id')
->first()
?->user_id;
//second time meeting is being held
if ($latestUserId) {
$nextUserId=DB::table('group_user')
->where('group_id', $req->groupID)
->where('user_id', ">", $latestUserId)
->orderBy('user_id')
->first()
?->user_id;
$mod = $nextUserId;
} else {
$mod = $firstUserId;
}
$data = new Meeting;
$data->groupID = $req->groupID;
$data->meetingDate = $req->meetingDate;
$data->meetingTime = $req->meetingTime;
$data->meetingModerator = $mod;
$data->save();
}
Model group.php
class Group extends Model
{
use SoftDeletes;
use HasFactory;
public $timestamps=true;
protected $dates = ['deleted_at'];
public function creators()
{
return $this->belongsToMany(User::class);
}
}
Model user.php
class User extends Authenticatable
{
use SoftDeletes;
use HasApiTokens;
use HasFactory;
use HasProfilePhoto;
use Notifiable;
use TwoFactorAuthenticatable;
/**
* The attributes that are mass assignable.
*
* #var string[]
*/
protected $fillable = [
'name',
'email',
'password',
'role'
];
protected $dates = ['deleted_at'];
public function grp()
{
return $this->belongsToMany(Group::class);
}
/**
* The attributes that should be hidden for serialization.
*
* #var array
*/
protected $hidden = [
'password',
'remember_token',
'two_factor_recovery_codes',
'two_factor_secret',
];
/**
* The attributes that should be cast.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
/**
* The accessors to append to the model's array form.
*
* #var array
*/
protected $appends = [
'profile_photo_url',
];
}
Model meeting.php
class Meeting extends Model
{
use HasFactory;
public function gr()
{
return $this->belongsTo('App\Models\Group','groupID');
}
}

Laravel resource: Get some of relations

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.

Lazy eager loaded relationship missing in toArray()

Laravel 5.8
I am lazy loading an user with the related customer which has a one-to-one-relation with a crmaccount-object
The models are working so that when i retrieve the eager-loaded entity it shows all of the nested relationships.
One row later i use the "toArray()" method on that object and the output is missing the third-level-relations.
The only thing which maybe some kind of special regarding the "crmaccount"-model is that it holds a column which is json an has to be casted.
Any idea what is going on here?
All of these happens in a middleware. No difference if i use with or load.
public function handle($request, Closure $next)
{
$UserData = \Auth::user();
if($UserData){
$User = \App\Login::with(['role','customer','customer.crmaccount'])->find($UserData->id);
dump($User);
dd($User->toArray());
$UserData['isAdmin'] = false;
if($UserData['role']['name'] === 'Admin'){
$UserData['isAdmin'] = true;
}
$request->request->add(['UserData' => $UserData]);
}
return $next($request);
}
Login
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
class Login extends Authenticatable{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password','customer_id','role_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 Role(){
return $this->belongsTo('App\Role');
}
public function Customer(){
return $this->belongsTo('App\Customer');
}
/**
* [hasOpportunities Ruft alle Opportunities des Users ab. Da diese lediglich zwei Entitäten weiter sind, kann anstatt von dot-notated Lazy-Load auch die hasManyThrough-ORM-Methode genutzt werden]
* #return [hasManyThrough-Relation] [Die hasManyThrough-ORM-Beziehung]
*/
public function hasOpportunities(){
return $this->hasManyThrough(
'App\Opportunity',
'App\Customer',
'id',
'customer_id',
'customer_id'
);
}
/**
* [hasSalesreps Ruft alle SalesReps des Users ab. Da diese lediglich zwei Entitäten weiter sind, kann anstatt von dot-notated Lazy-Load auch die hasManyThrough-ORM-Methode genutzt werden]
* #return [hasManyThrough-Relation] [Die hasManyThrough-ORM-Beziehung]
*/
public function hasSalesreps(){
return $this->hasManyThrough(
'App\Salesrep',
'App\Customer',
'id',
'customer_id',
'customer_id'
);
}
}
Customer
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Customer extends Model{
public $timestamps = false;
protected $visible = ['id','name'];
protected $fillable = ['name'];
public function crmaccount(){
return $this->hasOne('App\Crmaccount');
}
public function Salesreps()
{
return $this->hasMany('App\Salesrep');
}
public function Prospects()
{
return $this->hasMany('App\Prospect');
}
public function Trees()
{
return $this->hasMany('App\Salesreptrees');
}
public function Opportunities()
{
return $this->hasMany('App\Opportunity');
}
public function User()
{
return $this->hasMany('App\Login');
}
}
Crmaccount
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Crmaccount extends Model{
public $timestamps = false;
protected $visible = ['id','name','crm_system','customer_id','crm_api_config'];
protected $fillable = [
'name','crm_system','customer_id','crm_api_config'
];
protected $casts = [
'crm_api_config' => 'array'
];
public function customer(){
return $this->belongsTo('App\Customer');
}
}
On every model, there is a protected $visible = []; and protected $hidden = [] attribute. These control the attributes that are available when the model is converted to an object, array or json. This includes relationships, as Laravel internally converts them to attributes, so omitting them from visible, or including them in hidden will cause them to not be available.
In Customer.php:
protected $visible = ['id','name'];
Since crmaccount is not in that array, only id and name will be available. Simply add crmaccount to the array to handle:
protected $visible = ['id','name', 'crmaccount'];
Alternatively, use hidden to explicitly set the attributes you don't want to show, and relationship, if loaded via ->with() will show by default.

eloquent one-To-Many-To-Many

Hi everyone I start with Laravel and eloquent and already I have a problem.
I have users, each user can have multiple vehicles and a vehicle can have multiple rentals. I want to list all rentals of each vehicle belonging to the current user.
User model:
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function vehicule()
{
return $this->hasMany('App\Models\Vehicule');
}
Vehicule model:
use Illuminate\Database\Eloquent\Model;
class Vehicule extends Model
{
protected $fillable = [
'user_id',
'published',
'rented'
];
public function user()
{
return $this->belongsTo('App\User');
}
public function rental()
{
return $this->hasMany('App\Models\Rental');
}
Rental model:
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Rental extends Model
{
protected $fillable = [
'from_date',
'to_date',
'amount_total',
'vehicule_id'
];
public function vehicule()
{
return $this->belongsTo('App\Models\Vehicule');
}
}
You can use your existing relationships:
$rentals = $user->load('vehicule.rental')->pluck('vehicule.rental')->collapse();
Or add a HasManyThrough relationship to User:
public function rental()
{
return $this->hasManyThrough(Rental::class, Vehicule::class);
}
$rentals = $user->rental;

Resources