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

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
);

Related

How to use Model in function parameter to reduce code in laravel?

This is how i am trying to update record in my laravel function which doesn't work
public function completePacking(SaleOrder $saleOrder)
{
$saleOrder->update(['status' => 'Draft']);
}
it is working
public function completePacking($id)
{
$saleOrder = SaleOrder::findOrFail($id);
$saleOrder->status = 'Dispatched';
$saleOrder->save();
}
i want to use first method because it is less code but that is not working
Add 'status' to your $fillable attribute in your SaleOrder model.
Or remove 'status' from $guarded attribute in SaleOrder model.
After doing any of the following, you would be able to use your desired version to update status.
Read more on https://laravel.com/docs/5.7/eloquent#mass-assignment
$saleOrder = SaleOrder::where('id', $id)->update(['status' => 'Draft']);

Laravel do I have to worry about mass assignment when setting field by field

I am a bit confused when it comes to laravels mass assignment.
I know that I can protect fields using:
protected $fillable = [
'username', 'email', 'password'
];
and be protected here:
$flight = App\Flight::create(Input:all);
or
$flight->fill(['name' => 'Flight 22']);
But I only create or update Models like this:
public function createUser(NewUserRequest $request, User $newUser)
{
$newUser->insertUser($request);
}
insertUser looks like this:
public function insertUser($request)
{
$newUser = $this;
$newUser->user_type = (int) $request->input('user_type');
$newUser->username = $request->input('username');
$newUser->email = $request->input('email');
if ($request->filled('password')) {
$newUser->password = bcrypt($request->input('password'));
}
if ($request->filled('facebook_id')) {
$newUser->facebook_id = $request->input('facebook_id');
}
$newUser->save();
return $newUser;
}
As you can see I always pick what fields I want to insert and what data should be inserted. So do I really need to set my $fillable when I dont use the create() or fill() methods?
The purpose of mass assignment protection is to protect developers who source model properties direct from user input, for example:
Example::create($request->input());
Without mass assignment protection a user who knows about the underlying application architecture could inject values into fields they're not expected to have access to, e.g if your User field has an is_admin value they could change their is_admin to 1 instead of 0.
Mass assignment protection is only required when working with unsanitized user input and mass assignment protection is only enabled by default when mass assigning. You have 3 options for a secure application:
Make use of mass assignment and whitelist each property in $fillable
Assign values individually so there is no mass assignment protection, e.g: $user->name = 'John Doe'
Disable mass assignment protection and do not mass assign from user input, e.g:
protected $guarded = [];
Example::create($request->only('name', 'age'));
Example::create(['name' => $request->name, 'age' => $request->age]);
You do not need need to disable mass assignment protection in your example because you are not mass assigning values, you're assigning a value to each property individually. You can determine if you are using mass assignment by asking yourself "Am I passing in an array of properties and their values?".
You can learn more about mass assignment in the Eloquent documentation.

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();

custom `id` name using `insertGetId` fluent method of Laravel

According to Laravel's documentation:Inserts
Note: When using PostgreSQL the insertGetId method expects the auto-incrementing column to be named "id".
So, is there a workaround for a custom id name while using inserGetId. i.e.
$id = DB::table('users')->insertGetId(
['email' => 'john#example.com', 'votes' => 0]
);
You can use the Eloquent method Model::create() to return the object inserted, and obtain the object id, whatever his name is.
Try this:
$user = User::create(['email'=>'john#ecample.com','votes'=>0]);
$id = $user->custom_id;
This works if your User model is like:
class User extends Eloquent {
//This custom_id column needs to be of type serial in your table
protected $primaryKey = 'custom_id';
protected $fillable = ['email','votes'];
//...more code ...
}
I hope this works for you

passing an array from controller to model in laravel

I want to know that how to pass an array from laravel controller to laravel model .So that i can save them into db using a model . I don't want to make my controllers to heavy for that I am asking for this . When I have been saving form submissions into db where I should put my saving function ? in controller or model?
Laravel has something called Mass Assignment. It let's you pass an associative array and fills the model with those values. To make it work you have to define all the attributes you want to be able to mass assign in your model:
protected $fillable = ['foo', 'bar', 'and', 'much', 'more'];
Now you can just pass an array to the constructor of the model:
$input = [
'foo' => 'value1',
'bar' => 'value2',
'and' => 'value3',
'much' => 'value4',
'more' => 'value5',
];
$model = new Model($input);
$model->save();
Or even shorter, use the create() method which fills the model and directly saves it afterwards:
Model::create($input);
Try this..
//In Model get data from controller
public function functionname($data1, $data2){
//query
}
//In Controller sent data to Model
$data = Modelname::functionname($data1, $data2)->get();

Resources