I want to change field name and while fetching record from database
Ex.
$query = $formsElements->find('all')
->where(['Forms.slug' => 'allergy'])
->contain(['Forms'=>['fields'=>['id', 'name']], 'Elements']);
Above is my query and in same query i want to change name of "id" field as form_id.
Can you guys please suggest better ways to handle this without virtual field.
Thanks
you can use an alias, the manual says
You can set aliases for fields by providing fields
as an associative array:
So all you have to do is:
->contain([
'Forms'=>[
'fields'=>[
'form_id' => 'id',
'name'
]
],
'Elements'
]);
Related
I need to concat values in Laravel Update query.If Id value is 12, and If I need to append 14 to it, it should be 12,14.if ID value is null, then it should append as 14 instead of ,14.I used the following code,
$inscustrec =DB::table('configure')->where('POST_ID', $request->postid)
->update(
[
'ID' => DB::raw('CONCAT(COALESCE(ID),",'. $insrec.'")')
]);
i am getting comma as first character if the ID value is null.
I tried the following code,
$inscustrec =DB::table('configure')->where('POST_ID', $request->postid)
->update(
[
'ID' => trim(DB::raw('CONCAT(COALESCE(ID),",'. $insrec.'")'),",")
]);
But this code not working.
Any help would be greatly appreciated.
Give this a go (not sure on your SQL variant my example is using MySQL):
$inscustrec = DB::table('configure')->where('POST_ID', $request->postid)
->update([
'ID' => trim(DB::raw('CONCAT_WS(",", COALESCE(ID, "'. $insrec.'"))'))
]);
Hope $insrec does not come from user input as its interpolated directly into SQL.
I'm trying to update two tables in Laravel. But I don't know if you can do this while using an associative array with the help of Object->update($associative-array);
I have made an update sequence in laravel which updates a user and a location in two separate tables with a foreign key in the user table. I tried to update both tables doing update statements with the objects of the tables. I tried this in the following way:
$user->update($attributes);
$user->update($attributes); $location->update($attributes);
But this will only update the user table and skips the location table. The $attributes array contains multiple column data of the table user and location. The array is in order of the first column from the user table to the last column of the location table.
But neither of those tries updated both the tables. They only update user and skips location. As far as I know, is that you can do it this way with an associative array if the array contains the column data in the same order of a table and Laravel does the rest. With only updating the user table it does work, But I want it to work with two tables in the way It works using the update function with the object.
MySQL tables
users:
id
firstname
middlename
lastname
active
email
password
phone
mobile_work
phone_work
gender
position_id
settling_id
location_id
locations:
id
street
house_number
addition
zipcode
city
province
country
public function update(Request $request, User $user, Location $location)
{
$attributes = request()->validate([
'firstname' => 'min:3|max:50',
'middlename' => 'max:50',
'lastname' => 'min:3|max:50',
'active' => 'required',
'email' => 'min:3|max:100',
'gender' => '',
'phone' => 'numeric|min:8',
'mobile_work' => 'numeric|min:8',
'phone_work' => 'numeric|min:8',
'position_id' => '',
'settling_id' => '',
'location_id' => '',
'street' => 'required|min:3',
'house_number' => 'required|numeric',
'addition' => '',
'zipcode' => 'required|min:6|max:7',
'city' => 'required|min:3',
'province' => 'required|min:3',
'country' => '',
]);
$user->update($attributes);
}
If the way I'm trying to do it is impossible, I'd like to hear what the standard approach is in updating two tables within one update sequence.
What you try to do is not quite right. You should try to update the relation as well, and preferably first like
$location->update($locationAttributes);
$user->update($userAttributes);
By the way, it is not quite clear you want to update Location record or you want to associate a new Location to User. If it is latter then you can associate the Location to user like
$user->locations()->attach($locationId);
I made the mistake to not include the locations function from the model User into the update sequence.
User model:
public function locations()
{
return $this->hasOne(Location::class, 'id', 'location_id');
}
I fixed the problem by simply deviding the $attribute array to 2 arrays with their own table column data. I also made a second statement which calls the location function from the model and updates it accordingly.
$user->locations()->update($locationAttributes);
$user->update($attributes);
With $attributes only containing the user information and $locationAttributes only containing the location information.
$locations() refers to the row in the table locations. It knows which row to pick by taking the location_id from the selected user.
This function is not in the Laravel documentation, I have found it in the source code however I am not completely sure how it should be used. For example, if I am working with products, I want to either insert or update a product in the database based on its UPC. If a product with the same UPC exists, update it with the new values. If not, insert the new values as a new product. How should this be done using this function?
Thank you!
Insert or update a record matching the attributes, and fill it with values.
updateOrInsert(array $attributes, array $values = [])
https://laravel.com/api/master/Illuminate/Database/Query/Builder.html#method_updateOrInsert
DB::table('products')->updateOrInsert(
[
'upc' => $request->get('upc'),
],
[
'upc' => $request->get('upc'),
'name' => $request->get('name'),
'vendor' => $request->get('vendor'),
'description' => $request->get('description')
]
);
WHen i try to do :
$fields = array('id' => 'custom_id', 'title' => 'some_name');
The result I get has id as a string.
If I do:
$fields = array('custom_id', 'title' => 'some_name');
then it gives custom_id as integer.
How can I obtain custom_id as id without loosing the data type. I read the documentation but didn't found much help.
There is something that virtual fields can do I think. But is it possible inside the find query without the use of virtual fields etc?
Thanks in Advance
As of CakePHP 3.2
you can use Query::selectTypeMap() to add further types, which are only going to be used for casting the selected fields when data is being retrieved.
$query = $table
->find()
->select(['alias' => 'actual_field', /* ... */]);
$query
->selectTypeMap()
->addDefaults([
'alias' => 'integer'
]);
You can use any of the built-in data types, as well as custom ones. In this case the alias field will now be casted as an integer.
See also
API > \Cake\Database\Query::selectTypeMap()
Cookbook > Database Access & ORM > Database Basics > Data Types
Cookbook > Database Access & ORM > Database Basics > Adding Custom Types
With CakePHP 3.1 and earlier
you'll have to use Query::typeMap(), which will not only affect the selected field when data is being retrieved, but in various other places too where data needs to be casted according to the field types, which might cause unwanted collisions, so use this with care.
$query
->typeMap()
->addDefaults([
'alias' => 'integer'
]);
See also
API > \Cake\Database\Query::typeMap()
Change the type of existing columns
Changing the type of an existing column of a table is possible too, however they need to be set using a specific syntax, ie in the column alias format used by CakePHP, that is, the table alias and the column name seprated by __, eg, for a table with the Articles alias and a column named id, it would be Articles__id.
This can be either set manually, or better yet retrieved via Query::aliasField(), like:
// $field will look like ['Alias__id' => 'Alias.id']
$field = $query->aliasField('id', $table->alias());
$query
->selectTypeMap()
->addDefaults([
key($field) => 'string'
]);
This would change the the default type of the id column to string.
See also
API > \Cake\Datasource\QueryInterface::aliasField()
Hi my alternative example full, user schema() in controller Users add type column aliasFiels by join data:
$this->Users->schema()
->addColumn('is_licensed', [
'type' => 'boolean',
])
->addColumn('total_of_licenses', [
'type' => 'integer',
]);
$fields = [
'Users.id',
'Users.username',
'Users.first_name',
'Users.last_name',
'Users.active',
'Users__is_licensed' => 'if(count(LicenseesUsers.id)>=1,true,false)',
'Users__total_of_licenses' => 'count(LicenseesUsers.id)',
'Users.created',
'Users.modified',
'Languages.id',
'Languages.name',
'Countries.id',
'Countries.name',
'UserRoles.id',
'UserRoles.name',
];
$where = [
'contain' => ['UserRoles', 'Countries', 'Languages'],
'fields' => $fields,
'join' => [
'LicenseesUsers' => [
'table' => 'licensees_users',
'type' => 'LEFT',
'conditions' => [
'Users.id = LicenseesUsers.users_id'
],
],
],
'group' => 'Users.id'
];
// Set pagination
$this->paginate = $where;
// Get data in array
$users = $this->paginate($this->Users)->toArray();
WHen i try to do :
$fields = array('id' => 'custom_id', 'title' => 'some_name');
The result I get has id as a string.
If I do:
$fields = array('custom_id', 'title' => 'some_name');
then it gives custom_id as integer.
How can I obtain custom_id as id without loosing the data type. I read the documentation but didn't found much help.
There is something that virtual fields can do I think. But is it possible inside the find query without the use of virtual fields etc?
Thanks in Advance
As of CakePHP 3.2
you can use Query::selectTypeMap() to add further types, which are only going to be used for casting the selected fields when data is being retrieved.
$query = $table
->find()
->select(['alias' => 'actual_field', /* ... */]);
$query
->selectTypeMap()
->addDefaults([
'alias' => 'integer'
]);
You can use any of the built-in data types, as well as custom ones. In this case the alias field will now be casted as an integer.
See also
API > \Cake\Database\Query::selectTypeMap()
Cookbook > Database Access & ORM > Database Basics > Data Types
Cookbook > Database Access & ORM > Database Basics > Adding Custom Types
With CakePHP 3.1 and earlier
you'll have to use Query::typeMap(), which will not only affect the selected field when data is being retrieved, but in various other places too where data needs to be casted according to the field types, which might cause unwanted collisions, so use this with care.
$query
->typeMap()
->addDefaults([
'alias' => 'integer'
]);
See also
API > \Cake\Database\Query::typeMap()
Change the type of existing columns
Changing the type of an existing column of a table is possible too, however they need to be set using a specific syntax, ie in the column alias format used by CakePHP, that is, the table alias and the column name seprated by __, eg, for a table with the Articles alias and a column named id, it would be Articles__id.
This can be either set manually, or better yet retrieved via Query::aliasField(), like:
// $field will look like ['Alias__id' => 'Alias.id']
$field = $query->aliasField('id', $table->alias());
$query
->selectTypeMap()
->addDefaults([
key($field) => 'string'
]);
This would change the the default type of the id column to string.
See also
API > \Cake\Datasource\QueryInterface::aliasField()
Hi my alternative example full, user schema() in controller Users add type column aliasFiels by join data:
$this->Users->schema()
->addColumn('is_licensed', [
'type' => 'boolean',
])
->addColumn('total_of_licenses', [
'type' => 'integer',
]);
$fields = [
'Users.id',
'Users.username',
'Users.first_name',
'Users.last_name',
'Users.active',
'Users__is_licensed' => 'if(count(LicenseesUsers.id)>=1,true,false)',
'Users__total_of_licenses' => 'count(LicenseesUsers.id)',
'Users.created',
'Users.modified',
'Languages.id',
'Languages.name',
'Countries.id',
'Countries.name',
'UserRoles.id',
'UserRoles.name',
];
$where = [
'contain' => ['UserRoles', 'Countries', 'Languages'],
'fields' => $fields,
'join' => [
'LicenseesUsers' => [
'table' => 'licensees_users',
'type' => 'LEFT',
'conditions' => [
'Users.id = LicenseesUsers.users_id'
],
],
],
'group' => 'Users.id'
];
// Set pagination
$this->paginate = $where;
// Get data in array
$users = $this->paginate($this->Users)->toArray();