i want to convert my laravel select query with update query - php

This is my query:
$data = Collections::select(DB:raw("REGEXP_REPLACE(tour_id,'(,2|2,|2)','') as `new_tour_id"))->get();
I want to convert this query to update all my records in the database.
This is my database table shows:
I want this result:

Since Laravel 5.x allows attribute casting so it's possible to cast attributes to another data type for converting on runtime.
In this case, just declare a protected $casts property for example:
protected $casts = [
'tour_id' => 'array', // Will converted to (Array)
];
then store your ids like this
and finally search like this :
->whereJsonContains('tour_id', 3)->update([...]);
read more :
JSON Where Clauses

Assuming that you have a model for this table as Tour what you have to do is this:
$tours = Tour::select('tour_id')
foreach($tours as $tour) {
$tour->update([
tour_id = $whatever_id_to_update
]);
}

Related

How to convert data datetime from database?

i have data I get from database, it’s like this:
I want to convert it to datetime because it cannot be comparing to other variabel with time value, and it cannot because there a character and other object follow there.
This is error:
How to get just its datetime and don’t make it the other object follow on value ?
Use casting on your model. In this way laravel automaticlly convert attribute to expected type if it is possible.
// Your model class
class Booking {
protected $casts = [
'batasbayer' => 'datetime'
];
}
You may find other casts here.
Take value as $items[0]->batasbayar or if its in loop : foreach($items as $item){ $item->batasbayer }. And try converting $item->batasbayer
When you want a Model field to be retrieve as a Carbon instance you can add it to the protected $dates property of That Model
This is deprecated in Laravel 8
The recommended way is to pass that field name in the $casts property and specify the type in which you want to cast that field.
protected $casts = [
'batasbayer' => 'datetime'
];

Can we add custom values to a CakePHP Table Object?

I have a Cake Object when querying a table:
$invoices = TableRegistry::get('invoices')->find('all', ['conditions' => ['order_number =' => $orderNumber]]);
This works fine. I then want to add other array key/values to this Object, like this one:
$invoicesTmp = array();
$invoicesTmp['customer'] = "name of customer";
But $invoicesTmp is incompatible with $invoices. (one is an array, other is an CakePHP Object)
I have tried this:
compact($invoices, $invoicesTmp);
but that didn't worked.
The find() method of a Table object returns a Cake\ORM\Query object. This object is used to build SQL queries and to execute them. It has some features to define how the results from the query should be returned.
When CakePHP fetches results from the database the records are stored as an array, and CakePHP then converts them to Entity objects. A process called "hydration" of entities. If you disable hydration the records are returned as just an array.
$query = TableRegistry::get('invoices')
->find()
->where(['order_number'=>$orderNumber])
->enableHydration(false);
foreach($query as $record) {
pr($record);
}
The above creates a query object, and you can iterate over the query records because the object itself supports iteration.
The query object implements the Cake\Collection\CollectionInterface interface, which means we can perform a bunch of collection methods on it. The most common method is the toArray().
$invoices = TableRegistry::get('invoices')
->find()
->where(['order_number'=>$orderNumber])
->enableHydration(false)
->toArray();
The $invoices variable is now a valid array object holding the all the records with each record as an array object.
You can now easily use array_merge to assign extra metadata to each record.
$invoices = array_map(function($invoice) {
return array_merge(['customer'=>'name of customer'], $invoice);
}, $invoices);
$this-set(compact('invoices'));
Updated:
Based upon the comments it appears you wish to use two different tables with different column names, but those columns represent the same data.
Field Aliases
You can rename fields in the SQL query to share a common alias.
$table = TableRegistry::get($whichTable ? 'table_a' : 'table_b');
$records = $table->find()
->select([
'id',
'invoice_id',
'name' => ? $whichTable ? 'customer_name' : 'invoice_name'
])->all();
The above selects a different column for name depending upon which table is being used. This allows you to always use $record->name in your view no matter which table.
I don't like this approach, because it makes the source code of the view file appear to reference a property of the entity that doesn't really exist. You might get confused when returning to the code later.
Field Mapping
From a MVC perspective. Only the controller knows what a view needs. So it's easier if you express this knowledge as a mapping.
$map = [
'id'=>'id',
'invoice_id'=>'invoice_id',
'name' => ? $whichTable ? 'customer_name' : 'invoice_name'
];
$table = TableRegistry::get($whichTable ? 'table_a' : 'table_b');
$records = $table->find()
->select(array_values($map))
->all();
$this->set(compact('records','map'));
Later in your view to output the columns you do it like this:
foreach($records as $record) {
echo $record->get($map['name']);
}
It becomes verbose as to what is happening, and why. You can see in the view that the controller provided a mapping between something called name and the actual field. You also know that the $map variable was injected by the controller. You now know where to go to change it.

How can I make laravel casting array on the model?

I try like this
Data type of votes_detail in database is json
My model like this :
<?php
class Store extends Model{
protected $fillable = [ ...,'votes_detail',...];
protected $casts = [
'votes_detail' => 'array',
];
}
My controller like this :
$store = Store::find($id)
$votes_detail = $store->votes_detail;
dd($votes_detail);
The result of dd($votes_detail) is :
{"1": "1", "5": "2"}
Why the result is still json?
The result should be an array
Whereas I've set the array in cast model
How can I solve this problem?
You could use Laravel accessors. In you model define a method called exactly getVotesDetailAttribute($details):
public function getVotesDetailAttribute($details)
{
return json_decode($details, true);
}
then when you will call $store->votes_detail you will get the expected result.
After that you can use mutators to convert an array back to JSON when it is saved back in the DB. Define the method setVotesDetailAttribute($value) as follows:
public function setVotesDetailsAttribute($value)
{
$this->attributes['votes_detail'] = json_encode($value);
}
You can easily do it by converting your data to the array by using toArray() function. So it should be like
$store = Store::find($id)->toArray();
//$store contain a array.
$votes_detail = $store['votes_detail'];
make it dd($votes_detail) and get your desire result.
I think you are storing array data after json_encode() to a column which is not defined as json() in the migration like:
$table->text('votes_detail');
or
$table->integer('votes_detail');
And seems you have defined votes_detail as string, number or something else.
This is the reason behind your problem. So, define column type as json in migration like:
$table->json('votes_detail');
And then refresh your migration, your casting in the model will work and you will get your desired array.

Perform action on Laravel model once it has been filled with data

So I have a model that has a json field as an attribute. When it is retrieved, I'd like to convert that field into an array so I can do some other things with it.
For example, if the json has data like this {name:bob,email:sue} in a parameter called json, when the model object is built, I'd like it to something like this:
public function setJsonAttribute($value)
{
$this->attributes['json'] = $value;
$jsonInfo = json_decode($value, true);
$this->name = $jsonInfo['email'];
$this->email = $jsonInfo['name'];
}
This is an example of an attempt I did with a mutator, but it's not optimal. Is there any way to do this kind of thing automatically once the model has been loaded with data from the database?
Laravel 5.4
Eloquent includes a feature called array casting which converts a field from JSON to an array property on retrieval and converts the array back to a JSON string on saving.
You can enable this by adding a $casts property to your Model with the field name as the key and array as the value:
protected $casts = [
'options' => 'array',
];
https://laravel.com/docs/5.4/eloquent-mutators#array-and-json-casting
If you had options as {name:bob,email:sue} in the database, you would then access them as $model->options['name'] and $model->options['email'].

Building Eloquent query with "raw" column in column list

I'm using Eloquent to build a query, passing an array of columns to the get() method to specify the column names that I want returning; but I'd also like to add one calculated column
YEAR(CURDATE())-YEAR(`dateOfBirth`) - (DAYOFYEAR(CURDATE()) < DAYOFYEAR(`dateOfBirth`)) as AGE
I know that I can specify parts of a WHERE or HAVING clause as raw, or the entire query as raw if I create it manually; but I'd rather use Eloquent's fluent interface to build the query.
Is there any way I can define this one column in the SELECT list as raw so that Eloquent doesn't wrap it in backticks?
EDIT
Alternatively, is there any way I can define the model, perhaps with a callback, of creating an age property and calculating the value in PHP when the model is populated?
Alternatively, is there any way I can define the model, perhaps with a callback, of creating an age property and calculating the value in PHP when the model is populated?
You want an accessor in your model.
public function getAgeAttribute() {
// do an age calculation on $this->dateOfBirth here
return $age;
}
Calling $model->age would then spit out the result of the calculation.
After examining the Eloquent code, and noting that (with the exception of *) all entries in the fields array that's passed to the query get() method are wrapped in backticks unless they are Query\Expression objects, the solution that I came up with was:
$joins = [
];
$columnnames = [
'id',
'roleId',
'category'
]
$calculatedFields = [
new Illuminate\Database\Query\Expression(
"YEAR(CURDATE())-YEAR(`dateOfBirth`) - (DAYOFYEAR(CURDATE()) < DAYOFYEAR(`dateOfBirth`)) as age",
),
new Illuminate\Database\Query\Expression(
"CONCAT(`forename`, ' ', `surname`) as fullname",
),
];
$modelName = 'User';
$query = (empty($joins)) ?
(new $modelName)->newQuery() :
(new $modelName)->with($this->joins);
$results = $query
->get(
array_merge(
$columnNames,
$calculatedFields
);
);
Posted here for the benefit of anybody else struggling to find any documentation explaining how to do this.

Categories