Difference between save, fill, create in laravel eloquent - laravel

So i am new to laravel,
I don't know the difference between save, fill and create in laravel eloquent.
can anybody describe it?

save() method is when you already assign a value to a model instance. for example
$user = new User;
$user->name = "anything";
$user->save();
dd($user); // {'id': 1, 'name': 'anything'}
save() can also for update a value
$user = User::first(); // { 'id': 1, 'name': "anything" }
$user->name = "change";
$user->save();
dd($user); // {id: 1, name: "change"}
create() is a static function, need array parameter to create a new record
$user = User::create(['name' => 'new user']);
dd($user); // {id: 2, name: 'new user'}
fill() is same like save() method but without create a new record. need to create a new instance before can use fill()
$user = new User;
$user->fill(['name' => 'last user']);
echo count(User::all()); // We count users on DB and result is 2
$user->save(); // This will save 'last user' to DB
echo count(User::all()); // result is 3

The are kinda the same, but not quite.
//Creating User with fill()
$user = new User();
$user->fill($validatedUserData);
$user->save();
//Creating User with create();
$user = User::create($validatedUserData);
As you can see, create can do all of 3 lines(with fill function) with just one line. That's essentially a quality of life feature.
Both of this shown above does the same thing.
With that being said, you'd probably want to use create() when making a new entry. But for updating an item, it's better to just do something like this:
public function update(User $user, Request $request){
$validatedUserData = $request->validate([
//Validation logic here
]);
$user->fill($validatedUserData);
$user->save();
}
Note: You need to mark fields as fillable to use those fields with create() or fill().

Related

How To Get Auth ID form user table and grab it for store to other table on database

I want to get Auth ID from user who has logged in and then use the Auth ID to store on other table
User_detail Controller
this is my store function
$data = new ModelUser();
$user= new user();
$data->fill(Auth::user());
$data->id_user = Auth::get('id');
$data->jenis_kelamin = $request->jenis_kelamin;
$data->no_tlp = $request->no_tlp;
$data->jurusan = $request->jurusan;
$data->wilayah = $request->wilayah;
$data->save();
return redirect()->route('surveylist');
and this is function Login
public function LoginPost(Request $request)
{
$email = $request->email;
$password = $request->password;
$data = user::where('email',$email)->first();
if($data) //check email apakah ada atau tidak
{
if(Hash::check($password,$data->password))
{
Session::put('id',$data->id);
Session::put('full_name',$data->full_name);
Session::put('email',$data->email);
Session::put('login',TRUE);
return redirect('userdt');
}
else
{
return redirect('index')->with('alert','Password atau Email yang anda masukan salah !!! ' );
}
}
}
this is the routes files
Route::get('/index','UserController#show')->name('surevey.index');
Route::get('/logout','UserController#Logout')->name('user.logout');
Route::post('/registerpost','UserController#RegisterPost')->name('user.register');
Route::post('/loginpost','UserController#LoginPost')->name('user.login');
//reward routes
Route::get('/reward','RewardController#index')->name('reward.list');
//profile
Route::put('/editprofile/edit/{id}','UserController#edit')->name('profile.edit');
Route::post('/editprofile/update','UserController#update')->name('profile.update');
Route::get('/userdt',['middleware'=>'auth','uses'=>'UserController#userdetail'])->name('userdt.show');
Route::post('/userdt/store','UserController#store')->name('userdt.store');
//Survei
Route::get('/createsurvey','SurveyController#show')->name('survey.create');
Route::get('/surveylist','SurveyController#index')->name('survey.list');
Auth::routes();
ModelUser
protected $fillable = [
'id_user',
'jenis_kelamin',
'no_tlp',
'jurusan',
'wilayah'
];
protected $table ='user_detail';
public function user()
{
return $this->belongsTo(user::class);
}
and I get error like this
Argument 1 passed to Illuminate\Database\Eloquent\Model::fill() must
be of the type array, null given, called in
E:\Laravel\surevey\app\Http\Controllers\UserController.php on line 110
You don't need to use $data->fill(Auth::user()); as you have only single user_id field need to set.
Also you can get the current logged in user's id using. \Auth::user()->id
So your code would be as follow:
$data = new ModelUser();
$data->id_user = \Auth::user()->id;
$data->jenis_kelamin = $request->jenis_kelamin;
$data->no_tlp = $request->no_tlp;
$data->jurusan = $request->jurusan;
$data->wilayah = $request->wilayah;
$data->save();
return redirect()->route('surveylist');
Note: Make sure you have included auth middleware with your route.
Like:
Route::get('profile', ['middleware' => 'auth', function() {
// Only authenticated users may enter...
}]);
And you have followed the authuntication process carefully.
https://laravel.com/docs/5.2/authentication
Edited:
Your loging should be changed as:
public function LoginPost(Request $request)
{
$email = $request->email;
$password = $request->password;
if (Auth::attempt(['email' => $email, 'password' => $password])) {
// Authentication passed...
return redirect()->intended('userdt');
}
return redirect('index')->with('alert','Password atau Email yang anda masukan salah !!! ' );
}
If your reverse one-to-one relationship in the User Model looks like this:
public function detail()
{
return $this->hasOne(ModelUser::class);
}
And you are sure a user is logged in, you could simply do this
$data = Auth::user()->detail()->save($request->all());
return redirect()->route('surveylist');
Laravel's ORM takes care of the rest.
should be Auth::id() or Auth::user()->id but seems like your Auth::user() is returning a null.make sure you sessions, routes are set up properly.
use Auth::attempt()to login user

Best approach to Insert Data in Mysql through Laravel

Below are the two ways to insert data in MySql through laravel
Way 1:
$post = Post::create([
'title' => $request->input('title'),
'body' => $request->input('body')
]);
Way 2:
$post = new Post;
$post->title = $request->input('title');
$post->body = $request->input('body');
$post->save();
I just want to know which approach is better and why? Could anyone please tell which approach is better?
Model::create is a simple wrapper around this, if you look at its implementation:
public static function create(array $attributes = [])
{
$model = new static($attributes);
$model->save();
return $model;
}
save()
save() method is used both for saving new model, and updating existing one. here you are creating new model or find existing one, setting its properties one by one and finally saves in database
save() accepts a full Eloquent model instance
$comment = new App\Comment(['message' => 'A new comment.']);
$post = App\Post::find(1);`
$post->comments()->save($comment);
create()
while in create method you are passing array, setting properties in model and persists in database in one shot.
create() accepts a plain PHP array
$post = App\Post::find(1);
$comment = $post->comments()->create([
'message' => 'A new comment.',
]);

Gathering data from multi page form, and adding additional data

So I'm data from a multi-page form, the data is stored like this.
I'm using this tutorial https://www.5balloons.info/multi-page-step-form-in-laravel-with-validation/
public function store(Request $request)
{
$user = $request->session()->get('user');
$user->save();
return redirect('/home');
}
That works fine. But how do I add additional data manually using the arrow function? For example, I need to set a status, the ip address, ect. Something like 'status' => 1
Assuming this is the only place you want to add these values to users, you could just add the values after you got it from the session:
public function store(Request $request)
{
$user = $request->session()->get('user');
$user->ip_address = '127.0.0.1';
$user->status = 1;
$user->save();
return redirect('/home');
}
you can add addition data like:
if your $user is laravel object then
$user->setAttribute('status', '1');
or $user if array then
$user['status']=1;

How can I save my own profile using the same email address?

I am very new to Laravel, and I am creating an "update profile" page. All is well, except saving my profile. Since I have declared that email must be unique - I will get an error. Makes perfect sense. I have been reading through this SO post about what I think is the same problem.
I am using form requests to handle my validation:
public function rules()
{
return [
'name' => 'required',
'email' => 'required|unique:users,email,' . Auth::user()->id,
...
]
}
My controller:
public function store(UpdateAccountRequest $request)
{
$input = $request->all();
$user = new User();
$user->name = $input['name'];
$user->email = $input['email'];
if ($user->save()) {
...
}
...
}
It looks like I am getting the error on the mysql side:
Integrity constraint violation: 1062 Duplicate entry 'name#email.com' for key 'users_email_unique'
Coming from CodeIgniter, in the past I would have a hidden field with the user Id or something and check if the user id was editing their own account. If so, validation would pass. I'm not sure about the best way to go about this.
Thank you!
SOLUTION
Silly error on my part. I was creating a new user, then trying to save it. Which is why I was able to pass Laravel's validation, but not MySQL's unique index.
What I needed was this:
$user = User::find(Auth::user()->id); // Get the current user.
Instead of this:
$user = new User(); // Create a new user

Creating edit function in the same controller laravel

So I have a create function in my controller as shown below and my routes is as such, my question is is there a way for me to put a condition to different create and edit in the same function as both have quite similar coding. Can someone enlighten me pls?
class ManageAccountsController extends Controller
{
public function index() {
$users = User::orderBy('name')->get();
$roles = Role::all();
return view('manage_accounts', compact('users', 'roles'));
}
public function update()
{
// process the form here
// create the validation rules ------------------------
$rules = array(
'name' => 'required', // just a normal required validation
'email' => 'required|email|unique:users', // required and must be unique in the user table
'password' => 'required|min:8|alpha_num',
'password_confirm' => 'required|same:password', // required and has to match the password field
'mobile' => 'required',
'role_id' => 'required'
);
// do the validation ----------------------------------
// validate against the inputs from our form
$validator = Validator::make(Input::all(), $rules);
// check if the validator failed -----------------------
if ($validator->fails()) {
// redirect our user back to the form with the errors from the validator
$input = Input::except('password', 'password_confirm');
$input['autoOpenModal'] = 'true'; //Add the auto open indicator flag as an input.
return redirect()
->back()
->withInput($input)
->withErrors($validator);
} else {
// validation successful ---------------------------
// user has passed all tests!
// let user enter the database
// create the data for our user
$user = new User;
$user->name = Input::get('name');
$user->email = Input::get('email');
$user->password = Hash::make(Input::get('password'));
$user->mobile = Input::get('mobile');
$user->role_id = Input::get('role_id');
// save our user
$user->save();
// redirect ----------------------------------------
// redirect our user back to the form so they can do it all over again
Session::flash('flash_message', 'User successfully added!');
return redirect()->back();
}
}
}
routes.php
Route::get('manage_accounts', 'ManageAccountsController#index');
Route::post('manage_accounts', 'ManageAccountsController#update');
UPDATE OR CREATE
Try the updateOrCreate() in Eloquent to create or update a record matching the attributes.
Read API docs udateOrCreate()
Your code will be like:
Model::updateOrCreate( ['id' => $id], ['firstField' => 'value', 'secondField' => 'value'] );
Note: first parameter is the match to be found and second the data's to be saved.
Hope this is helpful.
Why don't you try moving some of this code out of your controller. If you were to use Repositories, then you would be able to encapsulate some of your logic in order to use it for both functions.
Also you can handle all this validation without writing all the extra code into your controller - see http://laravel.com/docs/5.0/validation#form-request-validation.
This may all seem a bit overkill at first, but once you get the hang of it, your code will be much more manageable and extendable.
(for more on these I would thoroughly recommend Jeffery Way's Laracasts https://laracasts.com/ - this helped me a lot when I was learning Laravel)
// routes.php
// http://laravel.com/docs/5.0/controllers#restful-resource-controllers
Route::resource('manage_accounts', 'ManageAccountsController');
// ManageAccountsController.php
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
class ManageAccountsController extends Controller
{
public $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function index() {
$users = User::orderBy('name')->get();
$roles = Role::all();
return view('manage_accounts', compact('users', 'roles'));
}
public function store(StoreUserRequest $request)
{
// validation already handled using this: http://laravel.com/docs/5.0/validation#form-request-validation
$this->userRepository->upsert($request)
Session::flash('flash_message', 'User successfully added!');
return redirect()->back();
}
public function update(StoreUserRequest $request, $id)
{
// validation already handled using this: http://laravel.com/docs/5.0/validation#form-request-validation
$this->userRepository->upsert($request, $id)
Session::flash('flash_message', 'User successfully updated!');
return redirect()->back();
}
}
// UserRepository.php
class UserRepository {
public function upsert($data, $id = null)
{
// You will also need something like this
if(isset($data['id']))
{
$user = $this->user->find($data['id']);
}
else {
$user = new User;
}
$user->name = $data['name'];
$user->email = $data['email'];
$user->password = Hash::make($data['password']);
$user->mobile = $data['mobile'];
$user->role_id = $data['role_id'];
// save our user
$user->save();
return $user;
}
}
}
Please use the code here as a guide (I have written this in a hurry and it will certainly contain errors). Have a quick read up on repositories and I think it should all make sense.
The basic premise here is to separate out code that you want to re-use rather than squashing it all into the same function.
Hope this helps!

Resources