will create method work on morphable model? - laravel

$comment = Comment::create(['title' => 'test']);
will this work with model that is morphable?
It has these columns:
$table->string('commentable_type');
$table->biginteger('commentable_id')->unsigned()->index();
it doesn't seem that they will be filled if I use create here or will they?
right now I am doing it like this:
$comment = new Comment();
$comment->title = $title;
$comment->body = $body;
$this->comments()->save($comment);
but would like to swtich to create so I can mass assign instead of one by one.

$this->comments()->create($array);
Is definitely available for morphable models.
From Taylor Otwell himself: https://github.com/laravel/framework/issues/322

Related

Doing ->save to multiple relations

I am using Laravel 5.5.13.
I have a model called Thumb. This thumb is related to two things in a many-to-one relationship: Player and Comment.
I currently do things like this:
public function store(Request $request, Entity $entity, Player $player)
{
$thumb = new Thumb($request->all());
$thumb->player_id = $player->id;
$entity->thumbs()->save($thumb);
return response()->json($thumb, 201);
}
We see how I have to set $thumb->player_id AND I don't have to set the entity_id because I am doing $entity->thumbs()->save
Is there a way to do $entityAndPlayer->thumbs()->save? Or is the way I did it above the recommend way?
You cannot use relationships to set 2 foreign columns so they way you showed is the correct one. However you can make it a bit cleaner in my opinion.
Into Thumb model you could add:
public function setPlayer(Player $player)
{
$this->player_id = $player->id;
}
and then instead of:
$thumb->player_id = $player->id;
you could use:
$thumb->setPlayer($player);
Or you could add create setPlayerAttribute method and finally instead of:
$thumb = new Thumb($request->all());
$thumb->player_id = $player->id;
use just:
$thumb = new Thumb($request->all() + ['player' => $player]);
You can't save multiple relationships at once but, for many to one associations you can use the method associate() (Laravel docs) to save using the belongs to part of the relationship, for example:
public function store(Request $request, Entity $entity, Player $player)
{
$thumb = new Thumb($request->all());
$thumb = $thumb->save();
$thumb->player()->associate($player);
$thumb->entity()->associate($entity);
return response()->json($thumb, 201);
}

Laravel 5.3 $model->save() values are always null however mass assignment works

Model
class Flight extends Model
{
protected $fillable = ['name'];
public $name;
}
In the controller
Flight::create(['name' => 'test']);
$flight = new Flight();
$flight->name = 'John'; //echo $flight->name 'John' it works
$flight->save();
The mass assignment creation works, however the method ->save() stores a null value for the object. I don't understand what I'm doing wrong. Please help!
Well, first of all, remove the public $name; from your model, why you need that?
Second, of all both:
Flight::create(['name' => 'test']);
and
$flight = new Flight();
$flight->name = 'John';
$flight->save();
Is correct.
And, where are you getting that null?

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

Inserting a new relationship

I'm just looking through the docs:
$post = Post::find(1);
$comments = array(
new Comment(array('message' => 'A new comment.')),
new Comment(array('message' => 'A second comment.')),
);
$post->comments()->save($comments);
I've implemented something similar to the above on my site, my question is, I wish to also insert a new Post at the same time, is there a way to do this, instead of using find?
Also what happens if the insert of the post fails, can I prevent the comments from being inserted?
Parent of the relationship must be saved prior to saving related models. Can't be done in 1 go. (btw push won't work for it either, in case you wonder).
$post = Post::create([ ... post data here ...]);
// or
$post = new Post;
$post->whatever = 'someValue';
$post->save();
// then
$post->comments()->saveMany($comments);
You can probably do it this way:
$post = new Post();
$post->title = 'my title';
$post->save();
$comments = array(
new Comment(array('message' => 'A new comment.')),
new Comment(array('message' => 'A second comment.')),
);
$post->comments()->saveMany($comments);
this way you will create new post and save comments for it. I haven't tested what happens if something goes wrong but I assume comments won't be inserted because there won't be related post id.
Why not first create a post then attach the related model something like this.
$post = new Post();
$post->save();
Then iterate through comments and assign the post_id attribute in comment table.
The id field of post model will be available if the post exists.
$comment = new Comment();
$comment->post_id = $post->id;
$comment->save();

How to: mass assign an update in Laravel 4?

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

Resources