laravel model event from trait not firing - php

why this is not working?? anything else i need to doo??? (note: i don't want to call any boot method from model). in models its working fine with booted method
// route
Route::get('/tests', function () {
return Test::find(1)->update([
'name' => Str::random(6)
]);
});
// models
namespace App\Models;
use App\Http\Traits\Sortable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Test extends Model
{
use HasFactory;
use Sortable;
protected $guarded = ["id"];
}
// traits
namespace App\Http\Traits;
trait Sortable
{
protected static function bootSort()
{
static::updated(function ($model) {
dd("updated", $model->toArray());
});
static::updating(function ($model) {
dd("updating", $model->toArray());
});
static::saving(function ($model) {
dd("saving", $model->toArray());
});
static::saved(function ($model) {
dd("saved", $model->toArray());
});
}
}

I got the answer if I want to fire model event from trait: I have to make the boot method name as trait class name with prefix boot
for example: if my trait name is Sortable the boot method name will be bootSortable
below is the full solution to question:
// route
Route::get('/tests', function () {
return Test::find(1)->update([
'name' => Str::random(6)
]);
});
// models
namespace App\Models;
use App\Http\Traits\Sortable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Test extends Model
{
use HasFactory;
use Sortable;
protected $guarded = ["id"];
}
// traits
namespace App\Http\Traits;
trait Sortable
{
// before
protected static function bootSort()
// after fix
protected static function bootSortable()
{
static::updated(function ($model) {
dd("updated", $model->toArray());
});
static::updating(function ($model) {
dd("updating", $model->toArray());
});
static::saving(function ($model) {
dd("saving", $model->toArray());
});
static::saved(function ($model) {
dd("saved", $model->toArray());
});
}
}

you can use laravel observers, it's much more simpler

Related

How to get data in api with employee number instead of id

I have created an api GET method to fetch child seminar table with parent users table that has employee_number column
Route::group(['prefix' => 'users'], function() {
Route::group(['prefix' => 'seminar'], function() {
Route::get("/{employee_number}", [UserProfileController::class, 'getSeminar']);
Route::post("/{user}", [UserProfileController::class, "createSeminar"]);
Route::put("/{seminar}", [UserProfileController::class, "updateSeminar"]);
Route::delete("/{seminar}", [UserProfileController::class, "deleteSeminar"]);
});
});
This is my Seminar model
<?php
namespace App\Models\Users;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Seminar extends Model
{
use HasFactory;
protected $table = 'users.seminars';
protected $fillable = [
'user_id',
'dates',
'name',
'certificate_number',
];
public function user()
{
return $this->belongsTo('App\Models\User', 'user_id');
}
public function seminarFiles()
{
return $this->hasMany("App\Models\Users\SeminarFile", "seminar_id");
}
}
This is my get method
public function getSeminar($employee_number)
{
$seminars = Seminar::with('user')->where('user_id', $employee_number)->get();
return response()->json($seminars, 200);
}
In my get method how do i compare the $employee_number value to seminar table. Do i do something like this
$seminars = Seminar::with('user')->where('user_id', $employee_number)->Auth::user()->id;
Is this the right path or should i do where('user_id', $id) instead
Any help would greatly appreciated.
public function getSeminar($employee_number)
{
$seminars = Seminar::with('user')
->where('users.employee_number', $employee_number)
->get();
return response()->json($seminars, 200);
}
If you want to get seminars of authenticated user, use this:
public function getSeminar()
{
$seminars = Seminar::with('user')
->where('users.employee_number', Auth::user()->employee_number)
->get();
return response()->json($seminars, 200);
}

laravel boot methods not working in the model

hi im using laravel 8 and im trying to do some code after create or update
like if model has create set created_by = Auth::user()->id ect
and this is my model code
<?php
namespace App\Models;
use Helper;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Notifications\Notifiable;
use Auth;
use App\Models\User;
use Spatie\Activitylog\Traits\LogsActivity;
class Account extends Model
{
use Notifiable,SoftDeletes,LogsActivity;
protected static $logAttributes =
[
'number',
'name',
'foreign_name',
'main_account_id',
'user_id',
'account_state_id',
'note',
'balance_limit',
'approved_state_id'
];
protected static $logName = 'accounts';
protected static $logAttributesToIgnore = [ 'updated_at'];
protected $table = 'accounts';
protected $fillable =
[
'number',
'name',
'foreign_name',
'main_account_id',
'user_id',
'account_state_id',
'note',
'approved_state_id',
'balance_limit',
'created_by','deleted_by'
];
public static function boot()
{
parent::boot();
self::creating(function($model){
$model->created_by = Auth::user()->id; // this code work
});
static::updating(function ($model) {
dd('asdf'); // this not working
});
self::deleting(function($model){
dd($model); // this not working
});
self::restoring(function($model){
dd($model); // this not working
});
}
}
now the code in
static::updating(function ($model) {
dd('asdf'); // this not working
});
is not working when i update any account also in delete and restore
the dd('asdf'); not working
any help here thanks ..
Please try to override the booted method instead of boot. It is an update from laravel 7.
protected static function booted()
{
static::created(function ($user) {
//
});
}
Check the official documentation on Using Closures

How can I get a pivot on my relationship in Laravel?

I have a relationship in my app. A candidate can have several "candidate_trainings" and each "candidate_training" is associated with a training. I wanted to avoid making "candidate_trainings" the piviot since it's hard to delete the right values when detaching, etc. So, how can I, on my hasMany relationship get the CandidateTraining model with the data from the Training model.
Here are my relationships:
<?php
namespace App;
use App\Traits\SanitizeIds;
use App\Salary;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Storage;
class Candidate extends Model
{
public function saveTraining($data) {
$this->candidateTrainings()->delete();
foreach(json_decode($data['training']) as $training) {
if(Training::find($training->training)->first()) {
$candidateTraining = new CandidateTraining;
$candidateTraining->description = $training->value;
$candidateTraining->training_id = $training->training;
$this->candidateTrainings()->save($candidateTraining);
}
}
}
public function candidateTrainings() {
return $this->hasMany('\App\CandidateTraining');
}
public function trainings() {
return $this->belongsToMany('\App\Training');
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Training extends Model
{
protected $fillable = ['name_french', 'name_english'];
public function candidates() {
return $this->belongsToMany('\App\Candidate');
}
public function candidateTrainings() {
return $this->hasMany('\App\CandidateTraining');
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Relations\Pivot;
class CandidateTraining extends Pivot
{
public function candidate() {
return $this->belongsTo('\App\Candidate');
}
public function training() {
return $this->belongsTo('\App\Training');
}
}
Thank you!
For you to be able to update the data directly on the CandidateTraining model, you need to add the $fillable fields to it.
protected $fillable = ['training_id', 'description'];
Your code should work! But if you don't mind, I did a little refactoring. You can accomplish this in another way:
<?php
namespace App;
use App\Traits\SanitizeIds;
use App\Salary;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Storage;
class Candidate extends Model
{
public function saveTraining($data)
{
// remove all relationships
$this->trainings()->detach();
// add new ones
foreach(json_decode($data['training']) as $training)
{
if(Training::find($training->training)->first())
{
$this->trainings()->attach($training->training, [
'description' => $training->value,
]);
}
}
}
public function candidateTrainings()
{
return $this->hasMany(App\CandidateTraining::class);
}
public function trainings()
{
return $this->belongsToMany(App\Training::class)
->withTimestamps()
->using(App\CandidateTraining::class)
->withPivot([
'id',
'training_id',
'description',
]);
}
}
That $training->training stuff is not readable, change it to something like $training->id if you are able to.
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Training extends Model
{
protected $fillable = ['name_french', 'name_english'];
public function candidates()
{
return $this->belongsToMany(App\Candidate::class)
->withTimestamps()
->using(App\CandidateTraining::class)
->withPivot([
'id',
'training_id',
'description',
]);;
}
public function candidateTrainings()
{
return $this->hasMany(App\CandidateTraining::class);
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Relations\Pivot;
class CandidateTraining extends Pivot
{
protected $fillable = ['training_id', 'description'];
public function candidate()
{
return $this->belongsTo(App\Candidate::class);
}
public function training()
{
return $this->belongsTo(App\Training::class);
}
}
If you want to access the pivot object from a controller:
$candidates = Candidate::with(['trainings'])->get();
foreach ($candidates as $candidate)
{
dd($candidate->pivot);
}

LARAVEL Why model events not fired for superclass Illuminate\Database\Eloquent\Model?

In ServiceProvider I have :
use Illuminate\Database\Eloquent\Model;
....
public function registerEvents()
{
Model::saved(function ($model) {
exit('saved');
});
}
And when I save User this is not working, but with :
use App\Models\BaseModel\User;
....
public function registerEvents()
{
User::saved(function ($model) {
exit('saved');
});
}
works fine ... why ?

Laravel 5.1 create not working

I am new to Laravel 5.1. I'm watching a tutorial video and in video teacher is using this code to insert data in database :
<?php
namespace App\Http\Controllers;
use App\comments;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
class CommentController extends Controller
{
public function getCommentNew()
{
$data = array(
'commenter' => 'soheil' ,
'comment ' => 'Test content' ,
'email' => 'soheil#gmail.com' ,
'post_id' => 1 ,
) ;
comments::create( $data );
}
}
I am doing the steps like him but I have a problem , all fields ecept created_at and updated_at will be empty like this :
this is my comments model :
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class comments extends Model
{
protected $fillable = ['commenter,email,post_id,comment,approved'];
public function post(){
return $this->belongsTo('App\posts');
}
}
and this is migration :
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateCommentsTable extends Migration
{
public function up()
{
Schema::create('comments', function (Blueprint $table) {
$table->increments('id');
$table->unsignedinteger('post_id');
$table->string('commenter') ;
$table->string('email') ;
$table->text('comment') ;
$table->boolean('approved');
$table->timestamps();
});
}
public function down()
{
Schema::drop('comments');
}
}
You haven't properly set the $fillable attribute in your Model, try with :
// in your model
protected $fillable = [
'commenter','email','post_id','comment','approved'
];
You have to define column names saperately on fillable array as shempignon described on above answer
Ex: ['column1', 'column2'...]
not in a single string. Each column name needs to be an array element
Try this and it'll be fine :) , you just forgot protected $table = 'comments';
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class comments extends Model
{
protected $table = 'comments';
protected $fillable = ['commenter','email','post_id','comment','approved'];
public function post(){
return $this->belongsTo('App\posts');
}
}

Categories