I'm using SPATIE laravel-activitylog I followed all the instructions but still it only log the Create function not update while using it on a Modal
My Modal
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Spatie\Activitylog\Traits\LogsActivity;
class Contact extends Model
{
use HasFactory, LogsActivity;
protected $fillable = [
'comp_name',
'cont_name',
'cont_email',
'cont_number',
'created_by',
'updated_by',
];
// spatie activitylog
protected static $logFillable = true;
protected static $logOnlyDirty = true;
protected static $logName='users'; // default
}
My Controller
Contact::where('id',$input['id'])->update($data);
$retrnArray = array('status'=>1,'msg'=>'Updated Successfully');
I have changed my query. we should use Eloquent query.
$contact = Contact::find($input['id']);
$contact->cont_email = $input['cont_email'];
$contact->cont_number = $input['cont_number'];
$contact->save();
$retrnArray = array('status'=>1,'msg'=>'Updated Successfully');
The Update with writing in DB but NOT writing in ActivityLogs will look like this:
User::where("id", 1)->update($data);
The Update with writing in DB and ALSO writing in ActivityLogs will look like this:
User::where("id", 1)->first()?->update($data); //if you are using php >= 8
User::where("id", 1)->firstOrFail()->update($data); // Good using php >= 5.6
User::find(1)?->update($data); //This also works as find("your id") also returns the model that it was able to found, it also returns null so check it on null or use nullsafe operator.
It's important to load model to make ActivityLogs correctly.
It seems the default log options does not include all Model`s field. You can describe fields that needs logging or use the wildcard to fire logging for every field changes. According to documentation example (in your Model Class):
public function getActivitylogOptions(): LogOptions
{
return LogOptions::defaults()->logOnly(['*']);
// To avoid hardcoding you could use logAll() method
// return LogOptions::defaults()->logAll();
}
Related
I'm using VueJS and Laravel for an application I'm developing. I've tried to search here for an answer, but I haven't found anything that works. Most of the times, it's because there's really nothing to return, but I've tried to debug my query quite a bit, and I don't understand why I keep getting a null.
So I'm trying to get information about the student who's logged in, so I'm doing an axios get on a route that executes the following:
public function getByUserId($id) {
//$student = $this->studentRepo->findByUserId($id);
$student = Student::where('user_id', $id)->first();
$inscription = Inscription::where('student_id', $student->id)->first();
$student->careers;
$res = $inscription ? new InscriptionResource($inscription) : '';
return response()->json([
'student' => new StudentResource($student),
'inscription' => $res,
]);
}
The thing is, it doesn't find the student with that user_id. I've checked if the user_id (param: $id) is getting there as expected and it is. I've also tried to get the query via ->toSql() and copy pasted the query on the database to test it and I do get the student I'm trying to search for. Thing is, it's not finding it in Laravel for some reason, I'm not sure why.
My student table does have the attribute "user_id", I've checked.
Student file:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Student extends Model {
use SoftDeletes;
protected $dates = ['deleted_at'];
public function charges() {
return $this->hasMany('App\Models\Payment');
}
}
Add the related column in the relation function
public function charges() {
return $this->hasMany('App\Models\Payment', '');
}
My repository is like this :
<?php
namespace App\Repositories;
use App\Models\UsersBank;
use Illuminate\Contracts\Container\Container;
use Rinvex\Repository\Repositories\EloquentRepository;
class UserBankRepository extends EloquentRepository
{
public function __construct(Container $container)
{
$this->setContainer($container)
->setModel(UsersBank::class)
->setRepositoryId('rinvex.repository.uniqueid');
}
}
My model is like this :
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class UsersBank extends Model
{
protected $fillable = ['user_id','bank_id','status','account_name','account_number'];
}
My service is like this :
public function setMain($id)
{
$param['status'] = 1;
$this->user_bank_repository->update($id, $param);
}
When setMain function executed, It will update field status = 1 by the id
I want to update status = 1 to all record. So, Not by id
How can I do it?
Note :
Update which I mean here is the update via the repository. Not update through a model
Look into the source code of update() method of the package and you'll see it's impossible, so you'll need to use foreach() and create a bunch of queries.
My opinion is this and similar packages are useless since they are still using Eloquent and do not provide any handful functionality. I'd recommend you to use Eloquent directly to update all rows with just one query:
Model::query()->update(['status' => 1]);
Hi I have created a mutator to only store digits on my phone numbers. Here is my code in my Profile Model.
public function setPhoneAttribute($phone)
{
$this->attributes['phone'] = preg_replace("/[^0-9]/","",$phone);
}
This works when I create a new record, but if I update the record it does not work. My question is how do I execute the Mutator on both create and update?
Here is how I update and create in my controller:
namespace App\Http\Controllers;
use App\Http\Requests;
use App\Http\Requests\ProfileRequest;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Auth;
use App\Profile;
class ProfileController extends Controller {
public function create(ProfileRequest $request)
{
// Check if the user does not have a profile yet
if(!Auth::user()->profile()->first()){
// Save to database
$saveToDatabase = Auth::user()->profile()->create($request->all());
return $saveToDatabase;
}
}
public function update(Profile $profile, ProfileRequest $request)
{
// Save to database
$saveToDatabase = Auth::user()->profile()->update($request->all());
return $saveToDatabase;
}
}
Here's what's happening:
Auth::user()->profile()->create($request->all()) calls the create method on your relationship (HasOneOrMany). This method then creates a new instance of the related model. This is important because obviously attribute mutators are only used when the record is created through the model.
However the relationship object doesn't have any update method. (It also wouldn't make sense to have one...). So what's happening instead is, when you do Auth::user()->profile()->update($request->all()). The update call get's proxied off to a query builder instance (that matches the relationship). This results in something like this being executed:
UPDATE profiles SET foo = 'bar' WHERE [relationship conditions]
It doesn't use the model at all. Therefore the mutator doesn't work.
Instead you have to call the update method on the actual related model. You can access it by just calling the relation as a property like this:
$saveToDatabase = Auth::user()->profile->update($request->all());
// ^^
// no parentheses
If the Profile model is injected correctly you actually might also just use that though:
public function update(Profile $profile, ProfileRequest $request)
{
// Save to database
$saveToDatabase = $profile->update($request->all());
return $saveToDatabase;
}
Using this code instead of your code
$saveToDatabase = Auth::user()->profile->update($request->all());
It's pretty straightforward as it's the most basic thing but I don't know what I'm missing:
Having a model called Site
I'm using Eloquent ORM, so when I call (in a controller)
$oSite = Site::find(1)
and then
var_dump($oSite);
It returns a value of NULL.
But when I check the database, the table 'sites' actually contains the following item:
id: 1
user_id: 1
name: test
In my Site model I have the following code:
use Illuminate\Database\Eloquent\ModelNotFoundException;
Class Site extends Eloquent {
protected $table = 'sites';
protected $fillable = ['user_id', 'name'];
}
Instead, if I gather the item with the following:
$oSite = DB::table('sites')
->where('id', 1)
->first();
It works and I get the correct register.
What I'm doing wrong? Which part of the documentation I didn't get?
EDIT:
Model code can be checked above.
Controller:
use Illuminate\Support\Facades\Redirect;
class SiteManagementController extends BaseController {
...
public function deleteSite()
{
if (Request::ajax())
{
$iSiteToDelete = Input::get('siteId');
$oSite = Site::find($iSiteToDelete);
return var_dump($oSite);
}
else
{
return false;
}
}
}
EDIT 2: (SOLVED)
Real reason why wasn't working:
I had originally in my model code the following:
use Illuminate\Database\Eloquent\SoftDeletingTrait;
use Illuminate\Database\Eloquent\ModelNotFoundException;
Class Site extends Eloquent {
protected $table = 'sites';
use SoftDeletingTrait;
protected $dates = ['deleted_at'];
protected $fillable = ['user_id', 'name'];
}
Problem was I added a 'deleted_at' column after I started the project and when I applied migrations, I didn't have softdeleting enabled.
Obviously, I did a second error, forgetting to enable 'deleted_at' to be nullable, hence all inserts went had a wrong timestamp (0000-00-00 ...).
Fix:
Made nullable 'deleted_at' column.
Set all wrong 'deleted_at' timestamps to NULL.
Check you are getting Input::get('siteId') correctly. if you are getting it then try to convert it into integer i.e
$iSiteToDelete = intval(Input::get('siteId'));
You're not returning your model.
var_dump prints output and returns nothing.
do this instead:
dd($oSite); // stands for var_dump and die - a helper method
and even better, simply return the model:
return $oSite; // will be cast to JSON string
In my case I was using a custom query with the DB facade. I neglected to skip records that have a deleted_at in my DB query. When showing all the records, it worked with IDs that had already been deleted, so methods like find that if they were considering the deleted_at, did not find the record.
Layer eight.
For the future if you encounter a similar problem you can check what SQL queries laravel is sending to the database.
Todo so just enable query logging by using DB facade:
\DB::enableQueryLog();
Before sending request to database.
Then after using find() or get() you can get all requests by:
\DB::getQueryLog();
You can getQueryLog into dd() function and see what database queries were made.
I'm currently studying eloquent of L4 and I encountered this mass assignment. I'd follow the instructions and I know you need to setup your $fillable to use the create method but I am still receiving a blank row in the database. here's my code:
MODEL:
class User extends Eloquent
{
protected $fillable = array('email','pwd','active','name');
}
CONTROLLER:
$user = new User;
$add = array(
'name'=>Input::get('custname'),
'active'=>1,
'pwd'=>Hash::make(Input::get('pwd')),
'email'=>Input::get('email')
);
return var_dump($user->create($add));
I also did:
CONTROLLER
$add = array(
'name'=>Input::get('custname'),
'active'=>1,
'pwd'=>Hash::make(Input::get('pwd')),
'email'=>Input::get('email')
);
return var_dump(User::create($add));
But still the same result.
There was a bug causing this, see https://github.com/laravel/framework/issues/1548
Should be fixed now, run composer update to get the newest version of laravel/framework
Yes with new version you can use public or protected keywords.
Simple use this :
protected $fillable = [‘email’, ‘pwd’,’active’,’name’];
You can also specify table name if you are working with other Model like this :
public $table = ‘users’
This is working fine after run composer update on the root of project directory.