Laravel Eloquent: inserting data - laravel

I am sending a bunch of data through post method. For now I am using a fully working solution:
$dataClient = new Client;
$dataClient->name = $post['client']['name'];
$dataClient->address = $post['client']['address'];
...
$dataClient->save();
I am wondering if there is a shorter solution? Like posting an array and Laravel could map keys to db fields?
What if you would add something more, like calculated value upon?
Example:
$dataClient = new Client;
Then map array keys to db keys
$dataClient->someField = someCalculatedValue
$dataClient->save();
Thank you in advance.

You have quite a few options when it comes to creating models from a data array. If you want to directly insert it into the database, the easiest way is create()
Client::create($post['client']);
If you want to change some things afterwards or just not save it right away, just pass your data to the constructor.
$client = new Client($post['client']);
$client->someField = 'some value';
$client->save();
And finally, the last option, calling fill() manually. This method is used internally for create() as well as in the constructor.
$client = new Client();
$client->fill($post['client']);
$client->save();
Note: for all methods above you'll need to set up the fillable attributes in your model. This is to protect against malicious user input (request data).
protected $fillable = ['name', 'address', 'etc'];
More information about Mass Assignment

Eloquent has create and update methods which will insert massive data. For example :
inputs = ['name' => 'value','address' => 'value'];
Client::create(inputs)
It will automatically map fields in Eloquent.

Have you tried something like this?
$dataClient = new Client;
$dataClient->fill($client);
$dataClient->save();
Depending on how you set up your Client model and what fields you set as guarded/fillable, the fill method will automatically map the data with their respective fields.

Related

Laravel eloquent make visible only given attribute in one instance of model

i have instance model from
$model = Model::find(1);
for example this instance always return these attribute (some is from $append):
-id
-name
-countRelation
-description
-created_at
-updated_at
what i want is to only retrive name and description from this instance;
makeVisible only work to show hidden attribute; i don't want use makeHidden because the result of find may change if on model i add new append attribute;
Since you are appending accessors limiting the SELECT statement won't stop those from being appended to the serializied output. You can use setVisible to do this though:
$model->setVisible(['name', 'description']);
Setting what is visible this way will limit the attributes, appends and relationships that are returned in the serialized output of the Model.
You can use select to only retrieve some column in your database, it will not affect append, see the doc for more info Eloquent
$model = Model::find(1);
// to this
$model = Model::select('name', 'description')->find(1);
See Query Builder for more insight about grabbing data from database.
if you retrieve name and description only, then you may use
$model = Model::select(['name', 'description'])->find(1);
You can use select() to select only certain columns in your query.
$model = Model::select('name', 'description')->find(1);
https://laravel.com/docs/8.x/queries#specifying-a-select-clause
You can also get the Model and use functions on the model. If you have a single Model you can use get().
$model = Model::find(1)->get('name', 'description');
If you have a collection you can use ->map->only(). This maps the only function as a callback for each Model in your Collection.
$models = $models->map->only(['name', 'description']);

How can I get the data inside my notifications from within my Controller?

I'm trying to get the numbers of records from my notifications, where the candidate_user_id column from inside the data attribute is the same as the UserId (Authenticated User).
After I dd, I was able to get the data from all of the records in the table by using the pluck method (Line 1). I then tried to use the Where clause to get the items that I need
but this just didn't work, it was still returning all of the records in the table.
DashboardController.php:
public function index()
{
$notifications = Notification::all()->pluck('data');
$notifications->where('candidate_user_id', Auth::user()->id);
dd($notifications);
}
Here is a partial screenshot of the data that is being plucked.
How can I get the data from this, in a way like this ->where('candidate_user_id', Auth::user()->id);?
If data was a JSON field on the table you could try to use a where condition to search the JSON using the -> operator:
Notification::where('data->candidate_user_id', Auth::id())->pluck('data');
Assuming you only want this data field and not the rest of the fields, you can call pluck on the builder directly. There isn't much reason to hydrate Model instances with all the fields to then just pluck a single field from them if it is just a table field, so you can ask the database for just the field you want.
The data in the data field is a json string, so you can tell Laravel to automatically cast it as an array using the $casts property on each of the models that is notifiable.
For instance, if you have a User model which uses the trait (ie has use Notifiable), add this:
protected $casts = [
'data' => 'array',
];
If you want to access all notifications for the auth user.
$user = auth()->user();
dd($user->notifications->pluck('data'));
If you really want to do in your question way, here is how.
$notifications = Notification::all()->pluck('data');
$notifications = $notifications->where('candidate_user_id', Auth::user()->id)
->all();
This assumes you that you did not modify the default laravel notifications relationship and database migration setup. If you have modified some of the default ones, you need to provide how you modify it.

Save vs update in laravel

What is the difference between save() and update() method in Laravel.
I have used save() method in case of update query but in few cases it acts as update and in few case it act as insert query function. Please let me know what exactly the difference between them.
These methods both allow you to save data to a database.
The save() method performs an INSERT when you create a new model which is currently is not present in your database table:
$flight = new Flight;
$flight->name = $request->name;
$flight->save(); // it will INSERT a new record
Also it can act like an UPDATE, when your model already exists in the database. So you can get the model, modify some properties and then save() it, actually performing db's UDPATE:
$flight = App\Flight::find(1);
$flight->name = 'New Flight Name';
$flight->save(); //this will UPDATE the record with id=1
Theupdate() method allows you to update your models in more convenient way:
App\Flight::where('active', 1)
->where('destination', 'San Diego')
->update(['delayed' => 1]); // this will also update the record
So you don't even need to assign the retrieved model to any variable. Updated properties are passed as arguments.
Examples and more info in the Laravel's docs.
There is only one thing left unsaid in what #ginopane told about the difference and it's that if you use update method on a query builder result then laravel will ignore $fillable or $guard array of your model. This is especially important if you want to use Input::all() as an argument to update:
Post::where('id', $id)->update(Input::all());
So in this case if you use App\Flight::where('active', 1)->update(Input::all()); everything in your database will be updated even if you put it in $fillable. So make sure to use save and update methods on Eloquent instance and not Query builder one. The following code will be fine even if the user submit fields that you don't want to insert or update in your databse table:
// User model
protected $fillable = ['email', 'name'];
// controller
public function update($id)
{
$user = User::findOrFail($id);
// validate the input here, use Request to do the job or whatever you like
$user->update(Input::all());
return view('some_view')->with('notice', 'user updated');
}
Now, no matter what with the FORM being passed here, only name and email will be updated.
Hope this complete #ginopane answer
save() : you can look to it as the equivalent of the INSERT in sql, it will create a new model (and insert it in the database)
To create a new record in the database, create a new model instance, set attributes on the model, then call the save method
update() : you can look to it as the equivalent of the UPDATE in sql, it will create a new model (and insert it in the database)
The save method may also be used to update models that already exist in the database. To update a model, you should retrieve it, set any attributes you wish to update, and then call the save method. Again, the updated_at timestamp will automatically be updated, so there is no need to manually set its value
code
$flight = App\Flight::find(1);
if (empty($flight)) {// you can do this condition to check if is empty
$flight= new Flight;//then create new object
}
$flight->name = 'New Flight Name';
$flight->save(); //this will UPDATE the record with id=1
for more detail doc

Update Table Using Laravel Model

I've got a table for a sports team. The record shows the team selection and some other information. I want to update the record with the team selection. My model is thus:
class Selection extends Model {
protected $table = "selection";
protected $fillable = [
'loose',
'hooker',
'tight',
'secrow1',
'secrow2',
'blindflank',
'openflank',
'eight',
'scrum',
'fly',
'leftwing',
'rightwing',
'fullback',
'sub1',
'sub2',
'sub3',
'sub4',
'sub5'
];
}
So I have a form which gives all the data for the positions and gives the id for the record in the DB. In my controller, I've got:
public function storeFirstTeam()
{
$input = Request::all();
Selection::update($input->id,$input);
return redirect('first-team');
}
But I get the following error:
Non-static method Illuminate\Database\Eloquent\Model::update() should not be called statically, assuming $this from incompatible context
Can anyone point out my silly error?
Please check the code below and this would solve your problem:
Selection::whereId($id)->update($request->all());
The error message tells you everything you know: you’re trying to call a method statically (using the double colons) that isn’t meant to be.
The update() method is meant to be called on a model instance, so first you need to retrieve one:
$selection = Selection::find($id);
You can then can the update() method on that:
$selection->update($request->all());
You should write it like given example below:
Selection::where('id', $input['id'])->update($input);
// Or use this using dynamic where
Selection::whereId($input['id'])->update($input);
Alternatively, you may write it like this as well:
Selection::find($input['id'])->fill($input)->save();
You can also simply update the fields manually:
Selection::whereId($id)->update($request->all());
it is possible to update with primary key but in my case I dont have id field in the detail table. To do it just run a query like this:
DB::table("shop_menu_detail")
->where(['name' => 'old name', 'language' => 'english'])
->update(['name' => 'new name']);
where is used as it is.

Laravel avoid relationship query on laravel after object creation

How to avoid querying relationship after object creation?
$store = new Store();
$store->name = 'Store 1';
$store->save();
return response()->json($store->products());
Laravel is querying products table. I would like to avoid that since I know there is none. This is just an example.
return response()->json([]); is not an option. In real world I really need to use $store->products().
Use the wasRecentlyCreated property of model to identify if the model was inserted during the current request lifecycle.
$data = $store->wasRecentlyCreated ? [] : $store->products();

Resources