How do I "json_decode" a single column data after fetch from database in Laravel? - laravel

I am saving an array in one column of my database using json_encode as follows and it works:
$service->description = $request->service_description;
$service->image = json_encode($url);
$service->duration = $request->service_delivery_time;
When I fetch the data I get a string. I am fetching using $service = Service::findOrFail($id);. I can decode the individual column as done below and pass it to the view.
$service = Service::findOrFail($id);
$images = json_decode($service->image);
return view('services.show',['service'=>$service , 'images'=>$images]);
What I am asking is, can I decode the images in one query?

Well this is a single query, json_decode runs after the SQL query returned your desired result.
What you can do is add a $casts property to your Service model so Laravel encodes/decodes it automatically for you, then you don't need to store these values with json_encode, just do $service->image = $url, and when you run findOrFail, the image property will already be a decoded json.
protected $casts = [
'image' => 'array',
];
Here's the documentation

You can use $cast or Accessor
1: $cast:
protected $casts = [
'image' => 'array'];
2: Accessor:
public function getImageAttribute()
{
return json_decode($this->attributes['image']);
}

Related

Laravel: Difference between $request->all() and $request->input()

What is the difference between $request->all() and $request->input()?
According to their documentation, they look very similar to each other:
You may retrieve all of the incoming request's input data as an array using the all method.
You may call the input method without any arguments in order to retrieve all of the input values as an associative array.
input() gets all input values and query string parameters.
all() is like input() but also includes all files.
$request->all()
usage comes if you wish to fetch all data passed as a collection.
Below is an example that gets all data and creates a record in your database table as per model usage.
public function post(Request $request)
{
$post = new Status();
$post->create($request->all());
}
$request->input()
Usage comes if you wish to fetch a variable passed as a single parameter.
Below is an example that gets data and creates a record in your database table as per model usage.
public function post(Request $request)
{
//get data as parameters passed from your form
$title = $request->input('title');
$author = $request->input('author');
//you can save data like this....This is just an example
DB::table('posts')
->insert([
'title' => $title,
'author' => $author,
'created_at' => \Carbon\Carbon::now(),
'updated_at' => \Carbon\Carbon::now(),
]);
}

Get formatted date at Eloquent results

Considering that the model is
class Cota extends Model
{
protected $fillable = ['status','user_id','produto_id','numero','arquivo','updated_at'];
protected $dates = [
'updated_at',
];
//protected $dateFormat = 'd/m/Y';
}
And considering the query:
$cotas = DB::table('cotas')->join('produtos','produtos.id','=','cotas.produto_id')->join('users','users.id','=','cotas.user_id')->select('cotas.id','produtos.titulo as produto','cotas.numero','cotas.arquivo','users.name','cotas.status','cotas.updated_at','produtos.valor')->get();
When I get only one instance, like:
$cota = Cota::find(6517);
I can do this:
$cota->updated_at->format('d/m/Y');
But in the query above, the results come always with the traditionl date format used by Mysql.
How do I get the results with the ('d/m/Y') format? I have to use a raw query? Is that the only way?
Thanks!
You can always user DB::raw in Select statement.
$cotas = DB::table('cotas')
->join('produtos','produtos.id','=','cotas.produto_id')
->join('users','users.id','=','cotas.user_id')
->select([
'cotas.id',
'produtos.titulo as produto',
'cotas.numero',
'cotas.arquivo',
'users.name',
'cotas.status',
DB::raw('DATE_FORMAT(cotas.updated_at, "%d/%m/%Y"') as updated_at,
'produtos.valor'
])
->get();
// Or Else You can always loop over your collection when displaying data / using that data.
You can use date casting like so
protected $casts = [
'updated_at' => 'datetime:d/m/Y',
];
This is only useful when the model is serialized to an array or JSON according to the docs.

Laravel insert into database request()->all() and addition

In laravel if i want to insert all the form input and i want to add text in one of the column why cant i use this code?
Example
$B2 = new B2;
$B2::create([
request()->all(),
$B2->column9 = "aaaa",
]);
The inserted database only insert column9, the other column is Null.
Because create() accepts an array as the only parameter:
public static function create(array $attributes = [])
You can do this:
$data = request()->all();
$data['column9'] = 'aaaa';
B2::create($data);
When ever you use request all you must first make sure that you have either fillable fields in your model or guarded = to an empty array so for example:
class B2 extends Model
{
protected $table = 'db_table';
protected $fillable = [
'email',
'name',
];
}
or you can use
protected $guarded = [];
// PLEASE BE CAREFUL WHEN USING GUARDED AS A POSE TO FILLABLE AS IT OPENS YOU TO SECURITY ISSUES AND SHOULD ONLY REALLY BE USED IN TEST ENVIRONMENTS UNLESS YOU REALLY KNOW WHAT YOU ARE DOING!
As for your create method you should make sure its an associative array like this:
$B2::create([
$B2->column9 => "aaaa",
]);
Or you could do something like:
$data = $request->except('_token');
$B2::create($data);
You'll have to merge the array.
$B2::create(array_merge(request()->all(), ['column9' => 'text']));
When you are adding to a database in that was it is called mass assignment. Laravel Automatically protects against this so you need to add the firld names to a fillable attribute in your model
protected $fillable = ['field1', 'column9'] //etc
https://laravel.com/docs/5.4/eloquent#mass-assignment
You also need to make sure you pass an array to the create method
$my_array = $request->all()
$my_array['column9'] = 'aaaa';
$B2::create(
$my_array
);

Laravel, how cast object to new Eloquent Model?

I get via Request a Json Object.
I clearly parse this object in order to check if it may fit the destination model.
Instead of assigning property by property. Is there a quick way to populate the model with the incoming object?
If you have an array of arrays, then you can use the hydrate() method to cast it to a collection of the specified model:
$records = json_decode($apiResult, true);
SomeModel::hydrate($records);
If you just have a single record, then you can just pass that array to the model’s constructor:
$model = new SomeModel($record);
Just pass your object casted to array as Model constructor argument
$model = new Model((array) $object);
Internally this uses fill() method, so you may first need to add incoming attributes to $fillable property or first create model and then use forceFill().
You should convert that object to array and use fill($attributes) method.
As method name says, it will fill object with provided values. Keep in mind that it will not persist to database, You have to fire save() method after that.
Or if You want to fill and persist in one method - there is create($attributes) which runs fill($attributes) and save() under the hood.
You can use Mass Assignment feature of Laravel,
You model would look like this:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = ['name', 'email', 'phone'];
}
And the process of populating the Model would be like this:
// This would be your received json data converted to array
// use 'json_decode($json, true)' to convert json data to array
$json_arr = [
'name' => 'User Name',
'email' => 'email#example.com',
'phone' => '9999999999'
];
$user = new \App\User($json_arr);
Hope this helps!
Castings may fail due to several reasons. A safe way is to add a static function to the model to generate from both array or object. feels like an extension to the model.
public static function generateFromObject($object)
{
$myModel = new MyModel();
foreach($object as $k => $v)
$myModel->{$k} = $v; //for arrays $myModel[$k] = $v;
return $myModel;
}
and you can use anywhere like,
$myModel = MyModel::generateFromObject($myObjectOrArray)->save();

how to print model query in laravel

i am new in laravel and have to save the record in table , i am using this code to insert the value
$model->studentRollId = $value1;
$model->resident_permit_number = $value2;
$model->save()
i am not getting any error but record not inserting in the table , so can anyone please tell me how can i print the executed query by the $model->save(), i tried DB::getQueryLog() but its not shiwing the query log so i can fin what is the issue . thanks in advance
Use ->toSql(), after your $model->save(), just do a dd($model->toSql())
Edit: Have you do a \DB::enableQueryLog();?
\DB::enableQueryLog();
$model->studentRollId = $value1;
$model->resident_permit_number = $value2;
$model->save()
dd(\DB::getQueryLog());
Try This
$model->studentRollId = $value1;
$model->resident_permit_number = $value2;
$data = $model->toSql();
dd($data);
Do you have studentRollId and resident_permit_number in the $fillable array?
Go to the $model and check if you have something like this:
protected $fillable = [
'studentRollId',
'resident_permit_number'
];
Another solution would be to insert data in raw like this:
DB::table('table_name')->insert([
'studentRollId' => $value1,
'resident_permit_number' => $value2
]);
Hope it helps.
Have you mentioned the column names in $fillable in you model. In laravel to insert a data in table you have to mentioned the columns names in $fillable method.
e.g.
Suppose you have users table and for that table you have User model.
In User.php add following method
protected $fillable = [
'list of columns'
];

Resources