I'm using Laravel 5 and I created a resource controller, setup routing and setup my database model.
My question is: when I do a POST, my store method is called on the controller but how can I take the request data and insert a new entry in the db without having to explicitly set every field?
Here's my code:
public function store(Request $request)
{
$data = $request->all(); // this grabs all my request data - great!
$user = new User;
$user-> ??? // insert ALL posted data
$user->save();
}
I understand that I can do...
$user->name = $request->name;
...for every field. But can someone tell me how to insert everything?
I realize I can probably do a foreach but I'm wondering if there's something better.
There is method fill in every model https://laravel.com/api/5.3/Illuminate/Database/Eloquent/Model.html#method_fill:
$user->fill($request->all());
Eventually you can use create:
\User::create($request->all());
This above is called mass asignment and there is section about this in Eloquents documentation https://laravel.com/docs/5.1/eloquent
You need to define which keys might be set:
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
// The attributes that are mass assignable
protected $fillable = ['name', 'login', 'birthdate'];
}
Related
CONTROLLER
public function update(Request $request)
{
DB::table('bahanbaku')->where('id', $request->id)->update([
'id_bb' => $request->id_bb,
'nama_bb' => $request->nama_bb,
'stok' => $request->stok
]);
dd($request);
return redirect('/bahanbaku');
}
Sorry for my bad english, but in my case,
After Submit, Data still same, not change
Can you help me? T.T
Id does not exist, this is quite basic, but i feel like there is some misunderstandings with Laravel. Just to get the basics down, in Laravel i would expect you to do the following.
Use models for database operations
Instead of passing the id on the request, pass it on URL parameters
Use model binding for getting your model.
Create your model, since it has a non standard table name define that. Add the properties you want to be filled when updating it as fillables.
use Illuminate\Database\Eloquent\Model;
class Bahanbaku extends Model {
protected $table = 'bahanbaku';
protected $fillables = [
'id_bb',
'nama_bb',
'stok',
];
}
In your route, define the model as a parameter.
Route::put('bahanbaku/{bahanbaku}', [BahanbakuController::class, 'update']);
Now the logic can be simplified to this, which will automatically handle if the model is not found and give you a 404 error.
public function update(Request $request, Bahanbaku $bahanbaku)
{
$bahanbaku->fill(
[
'id_bb' => $request->id_bb,
'nama_bb' => $request->nama_bb,
'stok' => $request->stok
],
);
$bahanbaku->save();
return redirect('/bahanbaku');
}
To improve even more, i would look into utilizing form requests.
What is the best way to add the authenticated user to a related model?
If I wanted to add the authenticated user as the author on a post model whenever a new post is created, what would be the best way to do it?
Currently, I have the following which does the job but it runs an extra query (i.e 1. Create post. 2. Update post with author_id).
public function store(Request $request)
{
$post = Post::create($request->all());
$post→author()->associate($request->user());
$post→save();
return new PostResource($post);
}
There must be a better way to do this. I was thinking of just adding all the attributes manually, with $post-author_id = $request→user()→id, and then calling $post-save(). However, I do not like the idea of having to manually write out all the other attributes of the post.
Another option I was thinking is by creating an event listener on the Post creating event. I do not know if this will reduce the need for an extra query.
What is the simplest solution?
Instead of using the create method, you could simply create a new instance of PostResource and fill it with author_id. So it would be a bundled query.
public function store(Request $request) {
$post = new Post($request->all());
$post->author_id = Auth::user()->id;
$post->save();
return new PostResource($post);
}
I hope it helps.
Maybe you can consider this on related model:
/**
* Save auth user on create
*/
protected static function boot()
{
parent::boot();
static::creating(function ($model) {
$userID = auth()->id();
$model->author_id = $userID;
});
}
I have a controller in Laravel that is adding a 'room' to the database, like this...
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Room;
class SitesController extends Controller
{
public function store(Request $request)
{
$this->validate($request, [
'name' => 'required',
]);
/* Create Post */
$room = new Room;
$room->name = $request->input('name');
$room->save();
return redirect('/room')->with('success', 'Room Created');
}
}
This works great but I would also like to write something to a different database table. Am I locked in to only updating the 'rooms' table in this controller or is there a way to modify others?
You are asking
to write something to a different database table,
not into a totally different database, right?
Why would you think you are locked in? Just use another Model that represents the table you want to update as well.
use App\YourOtherModel;
...
/* Create Post */
$room = new Room;
$room->name = $request->input('name');
$room->save();
$other = new YourOtherModel;
... go ahead
$other->save();
I'm new on laravel.
I have functions on my model php. I want to use them in controller and send to view.
This is my example function.
public function select()
{
$users = DB::table('user')->get();
}
now I need to use this on controller and view.
In codeigniter I handle it like this:
$data['content'] = $this->model->select();
$this->load->view('admin/users', $data);
in codeigniter we first load model then we call its one of its method and then we pass processed data to view . what is counter part of this in laravel 5
In Laravel 5 you can do it only using controller, like this:
public function select()
{
$users = DB::table('user')->get();
return view('admin.users',compact('users'));
}
if you want do it using Eloquent Model you need a model first. I assume you model name is User and your table name is users
User.php
protected $table = 'users'; // mention the table name
UserController.PHP
public function select()
{
$users = User::all(); // it will return a collection of data form User model
return view('admin.users',compact('users')); // write all variables you want pass through inside compact separated with comma
}
Something I find puzzling in Laravel 5 is how it handles the the deleting event and any changed attributes. Basically a soft delete is just an update of the deleted_at column on the table. I was trying to be clever and also include the user ID of the user making the delete. Problem is the deleting method ignores the changed attributes when passing them to the query builder.
Take this model for example.
<?php namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model {
use SoftDeletes;
protected $table = 'users';
protected $fillable = [
'user_name', 'created_at', 'created_by', 'updated_at', 'updated_by', 'deleted_at'
];
public static function boot() {
parent::boot();
// This works and updates my updated_by column
User::updating(function($user) {
$user->updated_by = 1;
});
// This is being ignored and does not update the updated_by column
User::deleting(function($user) {
$user->updated_by = 1;
});
}
}
I have traced the create, update and delete model methods. In every case my event listeners are being picked up and processed.
In the create and update save method though, there is a difference. Both of these methods call the getDirty() method which looks for changed attributes and passes the array to the query builder. This is why that insert or update event works.
The delete method however does not do this check and therefore does not pass those attributes to the builder. Although if you look at the stack during the entire oprtation, $this->model['attributes'] has my changed updated_at attribute! The builder just never uses it.
So I guess my question without re-writing the source how would you go about injecting an attribute into the delete method when using soft deletes. Like in my model example.
The end goal here is to update the updated_by field while doing a soft delete. I am trying to avoid first doing an update of the table then doing a delete.
Just override the method runSoftDelete inside your model
class User extends Model
{
protected function runSoftDelete()
{
$query = $this->newQuery()->where($this->getKeyName(), $this->getKey());
$this->{$this->getDeletedAtColumn()} = $time = $this->freshTimestamp();
$query->update(array($this->getDeletedAtColumn() => $this->fromDateTime($time), 'updated_by' => 1));
}
}
I think the problem is the updating event calls the save() function after the event, so any changes you do will be included in the save() call.
The delete event probably does not call the same save() function - so your changes are being lost.
Try to force the save yourself and see if that works?
User::deleting(function($user) {
$user->updated_by = 1;
$user->save();
});