How to: mass assign an update in Laravel 4? - laravel

This is an for internal app, mass assignment security is not an issue in this case.
I'm dealing with very large (numerous) form fields, so mass assigning the user edits would be great. Mass assignment seems to work fine with 'create()' but not with doing a find & save.
This is what I have:
$post_data = Input::all();
$formobj = HugeForm::find($id);
$formobj->save($post_data);
How do I go about it? I'd rather not specify many dozens of form inputs.

You should be able to use fill(array $attributes)...
$post_data = Input::all();
$formobj = HugeForm::find($id);
$formobj->fill($post_data);
$formobj->save();

In case of mass update it could be written even shorter.
$post_data = Input::all();
HugeForm::find($id)->update($post_data);

To allow mass assignment within Laravel you need to add:
protected $guarded = array();
Into your model. Basically this tells laravel not to protect any fields, you could also use:
protected $fillable = array();
And then set the fields you want to be fillable.
Hope this helps

This worked for me just 1 line (Laravel 8):
#ModelName::find($id)->update($request->all());

Related

Marking properties as fillable when using Laravel relationship functions

I have a Team model which can have many Site models attached, and has a createSite function to add sites:
public function createSite($domain) {
$site = new Site(['domain' => $domain]);
return $this->sites()->save($site);
}
Running this fails, as domain is not fillable. While easily fixed, I've read the docs on Mass Assignment and am trying to minimise which fields are fillable.
What's best practice here? Should I use $fillable or explicitly assign these properties (ie $site->domain = $domain)?
you can also protected $guarded = [] it is same as fillable but its functionality is opposite to the fillable you can read about it on the official web.

Populating $attributes with values from the previous model?

I've got a Laravel project (actually a Laravel Nova project) that involves entering a lot of data. To save some time I'd like to pre-fill some of the fields in my form, based on the logged in user's last entry.
I can pre-fill fields via the $attributes variable on my model, called Product, like so:
protected $attributes = [
'category' => 'ABC'
];
And I can do this for more dynamic data in the constructor like so:
function __construct() {
$this->attributes['category'] = Str::random();
parent::__construct();
}
But I'm not quite sure how I'd go about this when I want to retrieve what the user entered last time. For example, I'd like to do this:
function __construct() {
$user = auth()->user()->id;
$last = Product::where('created_by', $user)->latest()->first();
$this->attributes['category'] = $last['category'] ?? null;
}
However that ends up in an infinite loop. Same if I call $this->where('created_by' ...
Is there a way I can set $attributes of a new Product based on the last Product created by the user?
Nova fields have resolveUsing method, so in your case if you want to populate Text field:
Text::make('Category')->resolveUsing(function () {
return optional(auth()->user()->products()->latest()->first())->category;
})
I found the solution in the Nova Defaultable package.
Once you add the necessary traits, you can just add ->defaultLast() to a resource field and it'll default to the last set value. This also works for relationships which is perfect for my use case.

What is $model in Yii2?

I'm new to MVC and Yii Framework. The $model variable seems very confusing to me.
Where is it declared in the fist place? Where does it come from?
When I work with GridView I see that some functions take $model as a parameter. Neither model nor model search of this GridView declares $model variable anywhere. Yet it is widely used in all sorts of data management. It just doesn't make sense to me.
So I need a simple, straight forward, "for dummies" explanation of $model variable in Yii Framework v2. Help in clarifying these questions is much appreciated:
1. What is the origin of $model variable?
2. How to identify what model of the app is the $model variable representing when it's used in view files?
3. There are sometimes multiple $model variables in a single view file. Do all of them represent one model class? How to distinguish them when used for multiple classes?
Thanks.
If you are unsure where $model, $searchModel and other variables come from, you are most likely searching for them on the view file where they are used.
They are created on the controller that renders said view, just like any other object/variable.
From the controller, you can render a view and pass objects/variables the following way:
// MyController.php
...
public function actionMyAction($id) {
// Create and manipulate $model and $searchModel
...
/*
* First param is the name of the view to be rendered
* Second param is an Associative Array with params
* that will be made available to the view.
*/
return $this->render('my-view-name', [
'model' => $model,
'searchModel' => $searchModel,
]);
}
The $model is a var as the others ...normally in the yii2 samples contain an instance of a model class (as tiplically an active record=)
assuming you have a class
class Category extends \yii\db\ActiveRecord
{
........
a tipical code could be
$model = Category::findOne($id);
where Category::findOne($id) find an instance form database using $id as primary key and assign the result to $model ..
then you can access to the instance attribute (eg:attribute1) using
$model->attribute1
you can take a look at this guide
http://www.yiiframework.com/doc-2.0/guide-index.html
http://www.yiiframework.com/doc-2.0/guide-structure-models.html
http://www.yiiframework.com/doc-2.0/guide-db-active-record.html

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

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

Can you create a new Model instance without saving it to the database

I want to create a whole bunch of instances of a model object in Laravel, then pick the optimal instance and save it to the database. I know that I can create an instance with Model::create([]), but that saves to the database. If possible I'd like to create a bunch of models, then only "create" the one that is best.
Is this possible?
I am using Laravel 5.0
You create a new model simply by instantiating it:
$model = new Model;
You can then save it to the database at a later stage:
$model->save();
You can create instances with Model::make(). It works the same way as create but it doesn't save it.
Whether or not this is best practice is another matter entirely.
Yes, it is possible different ways: you can use the mass assignment without saving.
Please remember to set first the $fillable property in your model.
WAY #1: using the method fill
$model = new YourModel;
$model->fill([
'field' => 'value',
'another_field' => 'another_value'
]);
$model->save();
WAY #2: using the constructor
$model = new YourModel([
'field' => 'value',
'another_field' => 'another_value'
]);
$model->save();
In YourModel set the $fillable property with the fileds allowed for mass assignment:
class YourModel extends Model
{
protected $fillable = ['field', 'another_field'];
// ...
}
Laravel documentation: https://laravel.com/docs/9.x/eloquent#mass-assignment
there is also a method you can call it statically to get new instance:
$modelInstance = $modelName::newModelInstance();
it takes array $attributes = [] as a parameter

Resources