Any Way to Auto Guarded Timestamps? - laravel

$fillable = ['*']
Model::create($request->all()); // frontend can inject 'created_at'
$guarded = ['created_at', 'updated_at', 'deleted_at']
Can we auto guard timestamp?
I don't want to do this:
$fillable = ['field_1........field_20']

You can use except() method of Illuminate\Http\Request that will return all request fields but will exclude of the list the specified keys.
// try this...
Model::create($request->except('created_at', 'updated_at', 'deleted_at'));
You can create a BaseRequest class that override the Illuminate\Http\Request, same as:
<?php
namespace YourClass\Name\Space;
class BaseRequest extends Illuminate\Http\Request
{
const EXCEPT_FIELDS = ['created_at', 'updated_at', 'deleted_at'];
public function all()
{
return $this->except(self::EXCEPT_FIELDS);
}
}
and inject the new BaseRequest class into your controller instead of the Illuminate\Http\Request class.

Related

How to set a value using Mutators in a model?

I have a model where I am using a mutator for logged in user, assign id. But the value is not passed.
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Auth;
class Pass extends Model
{
use HasFactory;
protected $fillable = [
'title',
'user_id',
'source',
'category_id',
];
public function setUserIdAttribute()
{
$this->attributes['user_id'] = Auth::user()->id;
}
}
You should look at append Laravel documentation. Adding your attributes to the protected $appends array should add your attribute to your final model output.
So try:
protected $appends = ['user_id'];
Laravel has built-in methods to appends attributes to your model output. If for any reason, you cannot use those default methods, you can use setRawAttributes to dynamically add the field to your model. But laravel standard way should be better.
protected $attributes;
public function __construct(array $attributes = array())
{
$this->setRawAttributes(array(
'user_id' => Auth::user()->id), true);
parent::__construct($attributes);
}

Attach relation data directly to model

Article model
namespace App;
use Illuminate\Database\Eloquent\Model;
class Articles extends Model
{
protected $table = 'articles';
protected $primaryKey = 'idArticle';
protected $fillable = [
'idArticle', 'Topic', 'Image', 'Content', 'Views',
];
protected $hidden = [
'idCategory', 'idUser',
];
public function category()
{
return $this->hasOne(Categories::class, 'idCategory', 'idCategory');
}
}
So now when i call $article = Articles::find(1);, it will returns data from articles table, when i add $article->category;, it adds data $article->category->Name. I would like to have that Name directly inside $article - something like $article->category (so $article->category->Name into $article->category) is it possible to define that just using model class or i need to map it inside controller?
You can assign custom attributes to your Model classes. But you can't use the same property name as your category() method, because it's already accessed by $article->category.
An example giving you a property called category_name
class Articles extends Model
{
// attributes to append to JSON responses
protected $appends = ['category_name'];
// ... your other properties and methods
// your custom attribute
public function getCategoryNameAttribute()
{
if (!is_null($this->category)) {
return $this->category->Name;
}
return '';
}
}
Use as:
$article->category_name
You can use appends, as mentioned by #matticustard or just use the ->with() method while retrieving your model:
$article = Articles::find($id)->with('category');
Then, you can access the category name with:
$categoryName = $article->category->name;
Hope it helps.

laravel make a model have an attribute with value

I have a model called template and field template - when being called it doesn't exist, so how do I create a property or attribute called template when calling it this is being called through ajax. I tried making an accessor but it's not creating the attribute 'template' getTemplateAttribute($value) so I made a with('template') and I can't seem to create the attribute template in my model when being called.
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Template extends Model
{
protected $table = 'templates';
protected $fillable = ['title', 'directory', 'filename', 'created_at', 'updated_at'];
public function template() {
$this->attributes['template'] = 'test';
}
}
// and when calling it
public function show(Template $template)
{
$template = Template::findOrFail($template->id)->with('template');
return $template;
}
Use appends in model.. then use getAppendTypeAttribute(); the AppendType must be exact name as appends value..
class Template extends Model
{
protected $table = 'templates';
protected $fillable = ['title', 'directory', 'filename', 'created_at', 'updated_at'];
protected appends = ['template'];
public function getTemplateAttribute() {
return "test";
}
}
then
$template = Template::findOrFail($template->id);
return $template->template;

call collection with other model to lists

How do I call the relational data in the statement below using a with statement.
$suppliers = Supplier::with('user')->lists('user.company', 'user.id'); // doesn't work
class Supplier extends Model
{
protected $table = "suppliers";
protected $fillable = ['email'];
public function user() {
return $this->belongsTo('App\User', 'email', 'email');
}
}
You achieve your goal using the pluck method:
Supplier::with('user')->get()->pluck ('user.company', 'user.id');
The get method returns a Collection, then you can use its methods.

Laravel default user_id attribute in Model

I have a model
class Foo extends Model
{
protected $fillable = [
'name',
'user_id'
];
}
I would like to set Auth::user()->id by default to user_id column. So I added:
class Foo extends Model
{
protected $fillable = [
'name',
'user_id'
];
public function setUserIdAttribute()
{
$this->attributes['user_id'] = Auth::user()->id;
}
}
And from my controller I'm calling for Foo::create($data) without user_id key.
But it doesn't work as expected. store() gives Integrity constraint violation because of user_id is missing. (User already logged in to achieve create page)
i cannot find official documentation about model-observers for Laravel 5.6. but you can still do it by this code
public static function boot()
{
parent::boot(); // TODO: Change the autogenerated stub
// it will automatically add authenticate user to created_by column of selected model
static::creating(function ($model){
$model->created_by = auth()->user()->id;
});
}
You provide an example where you used accessors.
https://laravel.com/docs/5.1/eloquent-mutators#accessors-and-mutators
From official doc:
The accessor will automatically be called by Eloquent when attempting to retrieve the value of first_name:
If you want to set default value for some attributes you need to use Observers.
<?php
// file app/models/Foo.php
namespace App\Models;
use App\Observers\FooObserver;
class Foo extends Model
{
protected $fillable = [
'name',
'user_id'
];
public static function boot() {
parent::boot();
parent::observe(new FooObserver);
}
}
<?php
// file app/observers/FooObserver.php
namespace App\Observers;
use App\Models\Foo;
class FooObserver {
public function creating(Foo $model) {
$this->user_id = Auth::user()->id;
}
}
About model observers in official doc:
https://laravel.com/docs/5.0/eloquent#model-observers

Resources