How inject parameter in model constructor? - laravel

I'm trying to use mutator to change price property before saving in database. I want to inject discount parameter and use it in mutator like below. I'm getting error "Column not found: 1054 Unknown column 'discount' in 'field list" Is it possible to inject parameter in model constructor?
class Pizza2 extends Model
{
public $table = 'pizza2';
public $timestamps = false;
public $fillable = ['name', 'price'];
public function __construct($d = null)
{
$this->discount = $d;
}
public function setPriceAttribute($value)
{
if ($this->discount) {
$this->attributes['price'] = $value * $this->discount;
} else {
$this->attributes['price'] = $value;
}
}
}

Related

Livewire Datatables - Transform column and filter

I'm trying to substitute column data through callback, that has to return a username, mapped to user unique identifier. The list of usernames is outside of of the model' data and that's where I'm stuck.
I cannot use filterable() with the list of usernames because it will be incorrect since Eloquent won't be able to filter by username - only by user identifier.
The final result of below code is a query which does 'WHERE users.id = The username for X' instead of 'WHERE users.id = X'.
My model:
<?php
class User extends Model
{
protected $table = 'users';
protected $fillable = ['id'];
public static function getNamesProperty()
{
return ['Username #1', 'Username #2'];
}
}
class LogsTable extends LivewireDatatable
{
public $model = User::class;
public $exportable = true;
public $hideable = 'select';
public function builder()
{
return User::query();
}
public function columns()
{
return [
Column::callback(['id'], function ($id) {
return "The username for " . $id;
})->label('Username')->filterOn('users.id')->filterable(User::names()),
];
}
The question is how do I achieve the goal - be able to filter, while displaying username instead of identifier?
There is an answer on GitHub : https://github.com/MedicOneSystems/livewire-datatables/issues/284
Thank you Mark!

Error "Creating default object from empty value" Laravel update using one-to-one database

I have one-to-one database. It's Telepon in different table. So, every 'siswa' has one 'telepon' (telephon number). Telepon has 'sometimes' type not 'required'. It can be blank.
But, if it set blank, error "Creating default object from empty value" appears when i do update.
Code in Telepon Model :
class Telepon extends Model
{
protected $table = 'telepon';
protected $primaryKey = 'id_siswa';
protected $fillable = [
'id_siswa',
'nomor_telepon',
];
public function siswa() {
return $this->belongsTo('App\Siswa', 'id_siswa');
}
Code in Siswa Model for Telepon:
public function telepon() {
return $this->hasOne('App\Telepon', 'id_siswa');
}
This in Controller for update:
public function update(Siswa $siswa, SiswaRequest $request){
$input = $request->all();
$siswa->update($input);
$telepon = $siswa->telepon;
$telepon->nomor_telepon = $request->input('nomor_telepon');
$siswa->telepon()->save($telepon);
$siswa->hobi()->sync($request->input('hobi_siswa'));
return redirect('siswa');
}
Use the null coalesce operator ?? to check for null or create a new model instance:
$telepon = $siswa->telepon ?? new Telepon();

Relationship hasone trying to get property of non-object

I got a problem with relationship one to one mechanism for edit & update condition, so I have model Siswa and Telepon, with Telepon belongs to Siswa... here is the code
Siswa.php (model)
class Siswa extends Model
{
protected $table = 'siswa';
protected $fillable = [
'nisn',
'nama_siswa',
'tgl_lahir',
'jns_klmin'
];
protected $dates = ['tgl_lahir'];
public function getNamaSiswaAttribute($nama_siswa){
return ucwords($nama_siswa);
}
public function setNamaSiswaAttribute($nama_siswa){
$this->attributes['nama_siswa']=ucwords($nama_siswa);
}
public function telepon(){
return $this->hasOne('App\Telepon', 'id_siswa');
}
}
Telepon.php (model)
class Telepon extends Model
{
protected $table = 'telepon';
protected $primKey = 'id_siswa';
protected $fillable = [
'id_siswa',
'no_telepon',
];
public function siswa(){
return $this->belongsTo('App\Siswa', 'id_siswa');
}
}
Edit and update function controller shown as follows :
public function edit($id){
$siswa = Siswa::findOrFail($id);
$siswa->no_telepon = $siswa->telepon->no_telepon;
return view('siswa.edit', compact('siswa'));
}
public function update(Request $request, $id){
$siswa = Siswa::findOrFail($id);
$input = $request->all();
$validator = Validator::make($input, [
'nisn'=>'required|string|size:4|unique:siswa,nisn,'.$request->input('id'),
'nama_siswa'=>'required|string|max:30',
'tgl_lahir'=>'required|date',
'jns_klmin'=>'required|in:L,P',
'no_telepon'=>'sometimes|numeric|digits_between:10,15|unique:telepon,no_telepon,'.$request->input('id').',id_siswa',
]);
if ($validator->fails()) {
return redirect('siswa/'.$id.'/edit')->withInput()->withErrors($validator);
}
$siswa->update($request->all());
$telepon = $siswa->telepon;
$telepon->no_telepon = $request->input('no_telepon');
$siswa->telepon()->save($telepon);
return redirect('siswa');
}
I got Trying to get property of non-object error in edit function, line "$siswa->no_telepon = $siswa->telepon->no_telepon;".
When we call edit view inside edit controller, it will give a form which inside of it has previous saved data. no_telepon itself is a column from Telepon table, not Siswa, so how to show telephone saved data for editing purposes is the problem. FYI, create works just fine, and no_telepon data saved in Telepon table. So, how about this one? Any help appreciated.
It's probably because you don't have any 'App\Telepon' in the database with 'id_siswa' pointing to the id of the record from table siswa.
You can ommit this error in this way:
public function edit($id){
$siswa = Siswa::findOrFail($id);
$siswa->no_telepon = $siswa->telepon ? $siswa->telepon->no_telepon : '';
return view('siswa.edit', compact('siswa'));
}

Access Model Property In Laravel Mutators

I want to convert created_at dates to Persian date. So I implemented getCreatedAtAttribute function to do that. Because I just want to convert dates in special situations, I declared $convert_dates property in the model with default value as false.
class Posts extends Model {
public $convert_dates = false;
/**
* Always capitalize the first name when we retrieve it
*/
public function getCreatedAtAttribute($value) {
return $this->convert_dates? convert_date($value): $value;
}
}
$Model = new Posts;
$Model->convert_dates = true;
$post = $Model->first();
echo $post->created_at; // Isn't converted because $convert_dates is false
As you see in the codes above, it seems the model properties will be re-initial in mutators so the value of $convert_dates is always false.
Is there any other trick or solution to solve this problem?
This way you can set the constructor.
public function __construct($value = null, array $attributes = array())
{
$this->convert_dates = $value;
parent::__construct($attributes);
}
Now you can access this value in your mutator.
public function getCreatedAtAttribute($value)
{
return $this->convert_dates ? convert_date($value) : $value;
}
OR
Fill the protected fillable array like this:
class DataModel extends Eloquent
{
protected $fillable = array('convert_dates');
}
Then initialize the Model as:
$dataModel = new DataModel(array(
'convert_dates' => true
));

Laravel 4 - Model not being saved

Having this code:
class SearchIndex extends Eloquent {
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'searchindex';
//no timestamps
public $timestamps = false;
//mass-assignment
public $fillable = array('url', 'content', 'version', 'digest');
public $guarded = array();
public static function updateIndex($url, $version, $content)
{
self::retrieveSearchEntry($url, $version)->updateContent($content)->save();
}
public static function retrieveSearchEntry($url, $version)
{
try
{
return self::withoutContent()->where('url', $url)->where('version', $version)->firstOrFail(array('url', 'version', 'digest'));
}
catch(\Illuminate\Database\Eloquent\ModelNotFoundException $e)
{
return new SearchIndex(array('url' => $url, 'version' => $version));
}
}
public function updateContent($content)
{
$hash = md5($content);
if (!isset($this->digest) || ($this->digest != $hash))
{
$this->content = $content;
$this->digest = $hash;
}
return $this;
}
public static function search($content)
{
}
}
If I call updateIndex providing a new combination of url+version, an entry is created.
If I call updateIndex providing an existing pair of url+version, the entry is not updated with the new content. I'm seeing it has something to do with the fact that I'm omitting the 'content' field (reason: is huge, and I want to set it, not get it, in that function).
question: How can I not-get the content field, but be able to set it when saving?
Solved. Reason: I was not selecting the "id" field when doing the custom selection in firstOrFail(). In that way, id was null and the generated SQL tried to update (since it was an existent object) "where id is NULL", which would affect 0 rows.

Resources