How to insert a value to created_at field using Query Builder - php

I am new to Laravel. I am looking for a way to insert a value to specific field such as created_at automatically whenever the row is inserted to the DB table.
I found out that only Eloquent way which uses some Model->save() inserts timestamp to desired field.
But I want to be able to insert a value even when I use QueryBuilder. Is there any way to do so?
I have looked at this post: Query builder not inserting timestamps
Any advice would be appreciated.
Thank you in advance

You've said before you're using Model::insertGetId(), but the thing is this method is not using Eloquent. It's a Query Builder method. So, use create() instead:
$object = Model::create($data);
$id = $object->id;
If you still want to use insertGetId(), you'll need to add created_at timestamp manually:
$data['created_at'] = now();
Model::insertGetId($data);
Or you could set CURRENT_TIMESTAMP as a default for timestamp column, but it's so much better to just use Eloquent to handle this.

You can make a new helper methods in helpers.php
Something like this:
public function queryBuilderInsert($table, $data, $deleted_at = false)
{
$data['created_at'] = \Carbon::now();
$data['updated_at'] = \Carbon::now();
$deleted_at ? $data['deleted_at'] = null :;
\DB::table($table)->insert($data);
}
public function queryBuilderUpdate($builder, $data)
{
$data['updated_at'] = \Carbon::now();
$builder->update($data);
}
And then you can build your queries like this:
For insert use queryBuilderInsert method
$example_data = [
'name' => 'Name',
'email'=> 'Email'
];
queryBuilderInsert('users',$example_data);
If you're using soft deletes on your table you can use the third parameter of queryBuilderInsert
queryBuilderInsert('users',$example_data, true);
For update, you can make your query and then call queryBuilderUpdate method
$example_update_data = [
'name' => 'Name',
'email'=> 'Email'
];
$builder = \DB::table('users')->where('id',1);
queryBuilderUpdate($builder,$example_update_data);
It will set updated_at date and make update

Related

How do you write this sql query in laravel 5.4?

$user= Select from user where 'email' = $email AND 'specialty' =null OR 'address' = null OR 'country' =null OR 'state' = null;
This is the code i have but its not working properly. What i want is to return the row if any of the stated columns has its value as null.
$doctor= Doctor::where('email',$email)->where(function ($query) {
$query->orWhere('state','=','')
->orWhere('country','=','')
->orWhere('address','=','')
->orWhere('specialty','=','');
})->get();
First things first - in SQL to filter by NULL one should be using where x IS NOT NULL.
For the laravel part, Eloquent has a whereNull method, see more: https://laravel.com/docs/5.6/queries
So your eloquent code should look somehing like:
$doctor= Doctor::where('email',$email)->where(function ($query) {
$query->orWhereNull('state')
->orWhereNull('country')
->orWhereNull('address')
->orWhereNull('specialty');
})->get();

Join query retrieving data from only one table cakephp 3

I am new to cakephp. I am usign query builder to fetch details from two tables using join in cakephp query builder.But the query i am writing is fetching details only from one table. Need help to get data from other table as well.
This is my code to fetch data by joining two tables:
public function edit($id = null) {
$events_table = TableRegistry::get('Events');
$events = $events_table->find('all')
->hydrate(false)
->join([
'CourseType'=> [
'table' => 'coursetype',
'type' => 'LEFT',
'conditions' => 'Events.type = CourseType.coursetype_id',
]
])->where(['Events.id' => $id]);
$event = $events->toArray();
$this->set('event', $event);
}
As a result i am getting only details from events table. But i need data from coursetype also.Any help is appreciated. Thank you.
Manually adding joins won't cause any additional data to be selected, you'd have to do that on your own by specifying the fields to be selected via the select() method.
$events = $events_table
->find('all')
->hydrate(false)
->select($events_table)
// either add the fields one by one, or pass a table object
// as above to select all fields of the table
->select(['CourseType.id', 'CourseType.xyz', /* ... */])
// ...
I'd suggest to use use containments instead, ie setup the required association if not already present, and then simply use contain():
$events = $events_table
->find('all')
->hydrate(false)
->contain('CourseType')
->where(['Events.id' => $id]);
See also
Cookbook > Database Access & ORM > Query Builder > Selecting Data
Cookbook > Database Access & ORM > Query Builder > Loading Associations
your solution here: CakePHP find method with JOIN

Laravel eloquent does not update JSON column : Array to string conversion

I want to update a JSON column in my database but I get this error :
Array to string conversion
I have declared the column name as array in the model :
protected $casts = [
'destinations' => 'array'
];
this is the code that I use :
$data[] = [
'from' => $fromArray,
'to' => $toArray
];
Flight::where('id', $id)->update(['destinations' => $data]);
What should I do ?
You can access your json keys using the arrow so you can update your column like so:
Flight::where('id', $id)->update([
'destinations->from' => $data['from'],
'destinations->to' => $data['to']
]);
As #fubar mentioned you have to have mysql
5.7 in order to have my solution to work.
check the docs
This code did the work for me.
$user = User::where('id', $request->user_id)
->first();
$array_data = ["json_key3"=>"value"];
$user->forceFill([
'db_column->json_key1->json_key2' => $array_data
])->save();
According to this conversation on Github : Make json attributes fillable if Model field is fillable Taylor Otwell recommande the use of save method :
$model->options = ['foo' => 'bar'];
$model->save();
So in you case you can do it like this :
$flight = Flight::find($id);
$flight->destinations = $data;
$flight->save();
You're getting that error because you're trying to update your model using the Query Builder, which basically just creates raw SQL queries. It isn't aware of any data casting, etc defined within your model. You therefore have three choices:
1) Find your model, and run the update on your model instance.
$flight = Flight::findOrFail($id);
$flight->update(['destinations' => $data]);
2) Convert the data to a string before updating.
$data = json_encode($data);
Flight::where('id', $id)->update(['destinations' => $data]);
3) Use a database that supports JSON column queries, per #AmrAly's suggestion. Beware of this option, as not all databases support JSON columns.

How can I build a condition based query in Laravel using eloquent

I was wondering how can I build a condition based query in Laravel using eloquent?
I've found how to do it with a raw query but that that's not what I want also the answer to this question isn't that dynamic at least not as dynamic as I want it to be.
What I try to achieve is to create a dynamic WHERE query based on certain conditions, for example if the field is filled or not.
If I use the following code,
$matchThese = [
'role' => 'user',
'place' => \Input::get('location')
];
$availableUsers = User::where($matchThese)->take($count)->orderByRaw("RAND()")->get();
The query will fail if I don't send a location as POST value. I don't want it to fail I want it to skip to the next WHERE clause in the query. So basically if there's no place given don't search for it.
Build up the query and include the ->where() clause depending on whether or not you have the location in your input:
$query = User::where('role', 'user');
$query = \Input::has('location') ? $query->where('location', \Input::get('location')) : $query;
$availableUsers = $query->take($count)->orderByRaw('RAND()')->get();
Just build the array with an if condition:
$matchThese = [
'role' => 'user',
];
if(\Input::has('location')){
$matchThese['place'] = \Input::get('location');
}
$availableUsers = User::where($matchThese)->take($count)->orderByRaw("RAND()")->get();
$query = DB::table('table_name');
if($something == "something"){
$query->where('something', 'something');
}
$some_variable= $query->where('published', 1)->get();
You can use something like this.

Laravel 4 - How to turn timestamps off to update an entire collection

I'm trying to do a mass update on an eloquent collection.
So I have my query, which looks a bit like this:
\Responder::with('details')
->where('job_number', $project->job_number)
->where('batch_id', ((int) $batch_id) - 1)
->where('updated_at', '<=', $target_time)
->whereHas('transactions', function($q) {
$q->where('status', 'success');
}, '<', 1)
->whereHas('details', function($q) {
$q->where('email', '<>', '');
});
This query object is stored as $query (because I'm re-using it - the same reason I dont want to switch how I'm doing the query), I am then performing an update on the collection, e.g.
$query->update(array('batch_id' => $batch_id));
This works great except it updates all the 'updated_at' timestamps. Now i like the timestamps, they are used extensively elsewhere, so i cant turn them off all together but I thought I could disable them temporarily but I've tried the following:
$query->timestamps = false;
$query->update(array('email_drop_off_index' => $batch_id));
and I can confirm that doesn't work, is there a way to do this?
Any help much appreciated
timestamps = false should be made on your model, but what you are doing is setting the value on the query builder. That's why it is not being picked up.
timestamps is an instance variable so you can't set it statically, and I don't think there is a built-in way to do it from the query builder. So I suggest try instantiating the model first, then create a new query from it, like this:
$responder = new \Responder;
$responder->timestamps = false;
$query = $responder->newQuery()
->with('details')
->where('job_number', $project->job_number)
...; // the rest of your wheres
$query->update(array('email_drop_off_index' => $batch_id));
Here's a possible solution: subclass your Responder model and turn off timestamps in the subclass.
class MassUpdateResponder extends Responder
{
public $timestamps = false;
}
Then use your new class to do the updates. This seems like a bit of a hack, but it should work.
BTW, doing an update like the following worked for me:
$query->timestamps = false;
$query->value = "new value";
$query->save();
The update() method may be doing something different that's causing it to ignore the value of $timestamps.

Categories