Laravel not saving to database - php

For some reason I can't save to the database. No errors, just nothing updating. I know the commands are correctly working, because returning the $user afterwards gives me the respective fields modified. But somewhere the information isn't getting put into the database.
The blade can be found here: http://pastebin.com/8bAEsjtj
The request form can be found here: http://pastebin.com/ZCD1Xvjn
This is the controller:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests\UserFormRequest;
use App\UserEdit;
use DB;
use App\Http\Requests;
class EditUserController extends Controller
{
public function index()
{
$array = UserEdit::all()->toArray();
return view('UserEntry', compact('array'));
}
public function create()
{
//
}
public function store()
{
//
}
public function show($ID)
{
try {
$array = UserEdit::findorFail($ID)->toArray();
return view('UserEdit')->with('array', $array);
} catch(\Exception $e) {
return \Redirect::route('users.index')
->withMessage('This user does not exist');
}
}
public function edit(UserEdit $user)
{
return view('EditUser', compact('user'));
}
public function update(UserFormRequest $request, UserEdit $user)
{
//$input->$request->all();
//$user->fill(Input::all());
$user->fill([
'name' => $request->get('name'),
'email' => $request->get('email'),
'First_Name' => $request->get('First_Name'),
'Last_Name' => $request->get('Last_Name')
]);
//$user->name = Input::get('name');
//$user->email = Input::get('email');
//$user->First_Name = Input::get('First_Name');
//$user->Last_Name = Input::get('Last_Name');
$user->save();
//$user->save();
// return redirect()->route('users.index')->with('message', 'Details Updated!');
return $user;
}
public function destroy($id)
{
//
}
}
Pretty sure that's all above board, so why wouldn't it work? Am I missing some detail somewhere? This is the model: http://pastebin.com/vJBzfUVu

Ok. Found the answer, there's a difference between how mysql and php handle the 'id' in a database table.
In this instance, because I've inherited the database from other devs, the id column was capitalised.
This probably made the php laravel generates throw an error as it was looking for 'id' and didn't find anything.
I didn't notice this because it didn't actually print that error, and my other code was accounting for the capitalisation.
Changing the ID to id and fixing the references in my code seems to have solved the problem.

Related

why my validation rules in trait are not working when i call it from controller?

this us my trait. validation rules are not working even i give 1 for the page number getting
response not validation error.
trait ValidatePagination
{
protected function pagination(Request $request)
{
$rules['page'] = 'integer|gt:4';
$rules['per_page'] = 'integer|gt:0|lte:100';
$validator = \Validator::make($request->all(), $rules);
if ($validator->fails()) {
return response()->json($validator->errors(), Response::HTTP_BAD_REQUEST);
}
}
}
my controller's method
public function get(Request $request): JsonResponse
{
$companyId = $request['user']->cid;
$perPage = $request->query('per_page', 15);
$this->pagination($request);
$staffTable = TableBuilder::get($companyId, STAFF);
$staff = $staffTable->get(['pid', 'name', 'mobile', 'pay_rate', 'is_working', 'pay_start_date', 'pay_end_date']);
$staff = $staffTable->orderBy('updated_at', 'desc')->simplePaginate($perPage);
return $this->success('Fetched staff members', $staff);
}
The problem is, you are not using the returned data, you should throw an exception instead, this is kinda tricky to get the correct data into the validation exception. The most correct approach is to use form requests, which you can also reuse across controllers.
The request can be created by using php artisan make:request PaginatedRequest. For further information see the docs.
use Illuminate\Foundation\Http\FormRequest;
class PaginatedRequest extends FormRequest {
public function rules()
{
return [
'page' => 'integer|gt:4',
'per_page' => 'integer|gt:0|lte:100',
];
}
}
This will automatically resolve the validator and throw the correct exception. The pattern is also recommended as a good practice in Laravel best practices.
public function get(PaginatedRequest $request): JsonResponse
{
....
}
you should return the failed validation inside get function also like so:
public function get(Request $request): JsonResponse
{
$companyId = $request['user']->cid;
$perPage = $request->query('per_page', 15);
if ($validatorValue = $this->pagination($request)) {
return $validatorValue;
}
$staffTable = TableBuilder::get($companyId, STAFF);
$staff = $staffTable->get(['pid', 'name', 'mobile', 'pay_rate', 'is_working', 'pay_start_date', 'pay_end_date']);
$staff = $staffTable->orderBy('updated_at', 'desc')->simplePaginate($perPage);
return $this->success('Fetched staff members', $staff);
}
To me, it looks like you are missing returning the validation error from the controller code. An easy fix would be to run the validate instead of the fails code. I would say the most correct approach would be #mrhn solution since you should ideally create a FormRequest.
trait ValidatePagination
{
protected function pagination(Request $request)
{
$rules['page'] = 'integer|gt:4';
$rules['per_page'] = 'integer|gt:0|lte:100';
$validator = \Validator::make($request->all(), $rules);
$validator->validate();
}

PHP Laravel save() is not updating record

I am a beginner in laravel. I was updating records but I can't figure out what is wrong with my $student->save();
My controller code is as follows
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Student;
use PHPUnit\Framework\MockObject\Builder\Stub;
class HomeController extends Controller
{
public function read() {
$students = Student::all();
return view('read',['Students'=>$students]);
}
public function insert() {
return view('insert');
}
public function insertPost(Request $req) {
$student=new Student();
$student->Name = $req->input('name');
$student->Marks = $req->input('marks');
$student->save();
return redirect('/');
}
public function update($id) {
$student = Student::find($id);
return view('update',['Student'=>$student]);
}
public function delete($id) {
$student = Student::find($id);
$student->delete();
}
public function updatePost(Request $req) {
$student = Student::find($req->input('id'));
$student->Name=$req->input('name');
$student->Marks=$req->input('marks');
$student->save();
// Student::where('ID',$req->input('id'))
// ->update(['Name'=>$req->input('name'),
// 'Marks'=>$req->input('marks')]);
return redirect('/');
}
}
The Main main in updatePost(); is causing the records not updating
$student = Student::find($req->input('id'));
$student->Name=$req->input('name');
$student->Marks=$req->input('marks');
$student->save();
I changed the way of updating records to
Student::where('ID',$req->input('id'))
->update(['Name'=>$req->input('name'),
'Marks'=>$req->input('marks')]);
and it worked. But I wanted to know at which part I was making mistake in it.
You need to set your primary key to 'ID'
By default the primary key or PK name is 'id'
But in your code it changed to 'ID'
So you need to go to your User.php model class
and add this line
public $primaryKey = 'ID';
One thing you can try is using Laravel's update method. update will handle the save internally.
$student = Student::findOrFail($req->input('id')));
$student->update([
'Name' => $req->input('name'),
'Marks' => $req->input('marks'),
]);

Call to a member function update() on null

I'm building my first Laravel app. That's my first problem that I can't overcome.
I tried to google something about it, but I couldn't find something that could help me.
class ProfilesController extends Controller
{
public function index(User $user)
{
return view('profiles.index', compact('user'));
}
public function edit(User $user){
return view('profiles.edit', compact('user'));
}
public function update(User $user){
$data = request()->validate([
'description' => 'required',
]);
$user->profile->update($data);
return redirect("{$user->id}/edit");
}
}
I want to get through that and update $data.
Edit
public function profile() {
return $this->hasOne(Profile::class);
}
public function posts(){
return $this->hasMany(Post::class)->orderBy('created_at', 'DESC');
}
Try this:
optional($user->profile)->update($data);
You can see the official documentation of optional() helper here.
I think you cannot update directly on an instance, you'd have to do : User::where('user_id', $user->id);
If you want to "update" an instance, you would have to do : $user->description = $data['description']; $user->save();
Do this:
if($user->profile) {
$user->profile()->update($data);
}
Hope this will help you.
I would imagine this is because the user doesn't have a profile by default.
One way you can get around this is by using withDefault() on your profile relationship in your User model e.g.
public function profile()
{
return $this->hasOne(Profile::class)->withDefault();
}
You would then need to change your controller code slightly since the profile might not exist:
Change:
$user->profile->update($data);
To:
$user->profile->fill($data)->save();
I had the same issue. As it turned out I forgot to create a new empty profile while creating a new user. So i was calling an update on the user's profile in this case null.
Try adding this to the User model and later migrate:fresh your data.
protected static function boot()
{
parent::boot();
static::created(function ($user) {
$user->profile()->create();
});
}
This will create a new profile for user automatically.

Laravel 4 - redirect from a repository when not returning the called method

I am using a repository pattern in my Laravel 4 project but come across something which I think I am doing incorrectly.
I am doing user validation, before saving a new user.
I have one method in my controller for this:
public function addNewUser() {
$validation = $this->userCreator->validateUser($input);
if ( $validation['success'] === false )
{
return Redirect::back()
->withErrors($validation['errors'])
->withInput($input);
}
return $this->userCreator->saveUser($input);
}
Then the validateUser method is:
public function validate($input) {
$rules = array(
'first_name' => 'required',
'last_name' => 'required',
'email_address' => 'unique:users'
);
$messages = [
];
$validation = Validator::make($input, $rules, $messages);
if ($validation->fails())
{
$failed = $validation->messages();
$response = ['success' => false, 'errors' => $failed];
return $response;
}
$response = ['success' => true];
return $response;
}
This may be okay, but I dont like doing the if statement in my controller? I would rather be able to handle that in my validation class.
But to be able to redirect from the validation class, I need to return the method in the controller.
What if I then want to have 5 methods called, I cant return them all?
I would like to be able to simply call the methods in order, then in their respective class handle what I need to and if there is any errors redirect or deal with them. But if everything is okay, simply ignore it and move to the next function.
So example:
public function addNewUser()
{
$this->userCreator->validateUser($input);
$this->userCreator->formatInput($input);
$this->userCreator->sendEmails($input);
return $this->userCreator->saveUser($input);
}
If doing the if statement in the controller isn't as bad as I think then I can continue, but this seems incorrect?
For repository pattern, you can use this :-
setup your basemodel like this
<?php namespace App;
use Illuminate\Database\Eloquent\Model;
class BaseModel extends Model{
protected static $rules=null;
protected $errors=null;
public function validateForCreation($data)
{
$validation=\Validator::make($data,static::$rules);
if($validation->fails())
{
$this->errors=$validation->messages();
return false;
}
return true;
}
/**
* #return errors
*/
public function getErrors() { return $this->errors; }
}
now in your repository, add these methods
protected $model;
protected $errors=null;
public function model(){ return $this->model; }
public function getErrors(){ return $this->errors; }
public function create($inputs)
{
if(!$this->model->validateForCreation($inputs))
{
$this->errors=$this->model->getErrors();
return false;
}
$new=$this->model->create($inputs);
return $new;
}
and the controller will look like this..
public function postCreate(Request $request)
{
$inputs=$request->all();
if($new=$this->repo->create($inputs))
{
return redirect()->back()
->with('flash_message','Created Successfully');
}
return redirect()->back()->withInput()->withErrors($this->repo->getErrors())
->with('flash_message','Whoops! there is some problem with your input.');
}

How to pass and retrieve data between two controllers in Laravel

I'm trying to get to grips with Laravel and not finding the documentation any help at all. It seems to assume you know so much instead of actually walking new users through each section step by step.
I've got to the point where I need to make an internal call to another class, and sticking with MVC I can't seem to do what should be a simple thing.
My code:
class UsersController extends BaseController {
protected $layout = 'layouts.templates.page';
protected $messages;
public function getIndex()
{
$input = array('where', array('field' => 'email', 'operator' => '=', 'value' => 'tony#fluidstudiosltd.com'));
$request = Request::create('user/read', 'GET');
$users = json_decode(Route::dispatch($request)->getContent());
var_dump($users); exit;
$this->pageTitle = 'Fluid Customer Status :: Admin Users';
$this->content = View::make('layouts.admin.users');
}
}
Class UserController extends Base Controller
public function getRead()
{
$userId = (int) Request::segment(3);
if ($userId)
{
$user = User::findOrFail($userId);
return $user;
}
else
{
$users = new User;
var_dump(Input::all()); exit;
if (Input::has('where'))
{
var_dump(Input::get('where')); exit;
}
return $users->get();
}
}
Why isn't the input data from UsersController#getIndex available in UserController#getRead

Categories