I can't seem to save the updated profile to the database.
In my edit.blade.php:
{!! Form::model($user, ['method' => 'PATCH', 'route' => ['profile.update', $user->company_name] ]) !!}
// fields
{!! Form::submit('Update Profile', ['class' => 'btn btn-primary']) !!}
{!! Form::close() !!}
In my ProfilesController:
public function update($company_name)
{
$user = User::whereCompanyName($company_name)->firstOrFail();
$user->save(); // no validation implemented
flash('You have successfully edited your profile');
return redirect('/');
}
After hitting the update button, it shows the flash message on the homepage but the it's not saving to the database. Im coming from Rails and I feel I need to whitelist something.
The point is, you don't change your user model at all... You retrieve it, and then save it again without setting any fields.
$user = User::whereCompanyName($company_name)->firstOrFail();
// this 'fills' the user model with all fields of the Input that are fillable
$user->fill(\Input::all());
$user->save(); // no validation implemented
If you are using the above method with
$user->fill(\Input::all());
you have to add a $fillable array to your User Model like
protected $fillable = ['name', 'email', 'password']; // add the fields you need
If you explicitly want to set only one or two ( or three....) field you could just update them with
$user->email = \Input::get('email'); // email is just an example....
$user->name = \Input::get('name'); // just an example...
...
$user->save();
If you have tried the anwer Sinmok provided, you probably get the "whooops" page because you used
Input::get('field');
instead of
\Input::get('field');
On your Blade Syntax i assume you use laravel 5.
So as your controller is namespaced you have to add a \ before Input to reference the root namespace ( or put a use statement on top of your class)
Generally on your development server you should enable debugging. Then you have more detailed information about what's going wrong than just the pure.. "whoops... "
In your config/app.php file you can set
'debug' => true;
OR
you have a look at http://laravel.com/docs/5.0/configuration
And use the .env file.
If you use the .env file make sure there is an entry with something like
APP_DEBUG=true
then you can access that value in your config/app.php with
'debug' => env('APP_DEBUG'),
There should be a .env.example in your installation to give you a clue how such a file could look like.
UserController update function look like that :-
public function update(Request $request)
{
$user = Auth::user();
$data = $this->validate($request, [
'name' => 'required',
'email' => 'required',
]);
$user->name = $data['name'];
$user->email = $data['email'];
$user->save();
return redirect('/user_edit/'.Auth::user()->id)->with('success', 'User has been updated!!');
}
Looks like you've not set the submission values to the user object.
Try (Update this is for Laravel 4)
$user = User::whereCompanyName($company_name)->firstOrFail();
$user->field = Input::get("some_field"); // Name of the input field here
$user->save(); // no validation implemented
flash('You have successfully edited your profile');
return redirect('/');
EDIT
Actually, if you're using Laravel 5 it looks like it should be:
$user->field = Request::input('some_field'); // Name of the input field here
$user->save(); // no validation implementedenter code here
Related
I'm trying to have a button pass a query to the database when it's clicked. I'd like to have this set within a Controller that also stores requests and deletes requests. I was able to write to the database using store() and destroy(), but my edit() function gives me routing trouble. What is the best method to edit records using a controller? How would you build the edit() function? Or...should I be using the Update() function? I'm a Laravel/PHP beginner, please explain your answers if you can. Thank you!!
Overview: The project is an employee records table. I want to click a button that changes the employment status of an employee. I already have buttons to add new employee and delete and employee using this same Controller.
This is the route I set for the page:
Route::resource('employees', 'EmployeeController');
This is the front end form code for the button:
$workers = DB::table('employees')->get();
#foreach($workers as $employee)
{!! Form::open(array(
'method' => 'edit',
'route' => [ 'employees.edit', $employee->id]
)
)
!!}
<button type="submit">Release </button>
{!! Form::close() !!}
#endforeach
This is my store function and destroy function:
public function store(Request $request)
{
// Confirm Both Fields Are Not Empty
$this->validate($request, [
'first_name' => 'required',
'last_name' => 'required',
]);
//Add a new employee using the request data
$employee = new Employee;
$employee->first_name = request('first_name');
$employee->last_name = request('last_name');
$employee->position = request('position');
$employee->salary = request('salary');
$employee->hire_date = request('hire_date');
//$employee->attach = request('attach');
//Save it to the database
$employee->save();
//And then redirect back to the Employees page
return redirect('/employees');
}
public function destroy($id)
{
$employee = Employee::find($id);
$destroysignal = $employee->delete();
if($destroysignal) {
return redirect('employees');
}
}
You don't edit records, you update them. In your case you need an update() function in your controller
public function update(Request $request, $id)
{
$employee = Employee::findOrFail($id);
$employee->employment_status = true; //or false or whatever your statuses are
$employee->update();
return redirect()->back()->with('message', 'Employee updated!');
}
In your form, use the update route instead
{!! Form::model($employee, [
'method' => 'PATCH',
'route' => ['employees.update', $employee->id]])
!!}
<button type="submit">Release </button>
{!! Form::close() !!}
When using resource routes, 'route' => [ 'employees.edit', $employee->id] will most like to open a page where you want to edit the object. And the route will be bound to the edit($id) function of your controller.
With that said, the edit route doesn't need a form. A simple anchor would do
Edit Employee
I am new with PHP and Laravel.
I am using Laravel Framework version 5.3.29 and PHP 7
I am making extend register form with two parts.
register form which makes login credentials; Username and password
and after login credentials has been created, second part is creating profile to new user.
Process: Register form save data to user table and use user model.
after succesfully created username & password, it will redirect to
profile form and send post data to proceed form and validation.
Profile form is using profile model.
1) how to troubleshoot, when data has been sent by post method and n there is no error message. it only return back to profile form after submit button has been pressed.
2) I can see there is no data save to profile table.
register (user table) and profile table are in same database as
register form can save it, database part works fine.
code skeleton has made from "php artisan make:auth
complete code can be found https://github.com/mikromika/project1/
my route file is following:
// Registration Routes
Route::get('auth/register', 'Auth\RegisterController#getRegister');
Route::post('auth/register', 'Auth\RegisterController#register');
// Show profile form
Route::get('bio/create', ['as' => 'bio.create', 'uses' => 'Bio\ProfileController#create']);
Route::post('bio/store', ['as' => 'bio.store', 'uses' => 'Bio\ProfileController#store']);
ProfileController:store
this should validate data and save it to profile table
public function store(Request $request)
{ $this->validator($request->all())->validate();
$this->guard()->login($this->createx($request->all()));
Session::flash('success', 'Data was successfully save!');
if ($exception instanceof TokenMismatchException) {
Session::flash('success', 'Data was failed to save!');
return redirect('/auth/login');
}
// show profile form info after success post; does not work yet
return redirect()->route('bio.show'); }
Here is profile form way to send post method.
<form id="profile-form" action="{{ url('/bio/store') }}" method="POST" form class="form-horizontal">
{{ csrf_field() }}
post method is never reach that ProfileController:store part.
I have tried to use "GET" method, but I'm getting error
MethodNotAllowedHttpException in RouteCollection.php line 218:
I have changed route to
Route::get('bio/store', ['as' => 'bio.store', 'uses' => 'Bio\ProfileController#store']);
and form <form id="profile-form" action="{{ url('/bio/store') }}" method="GET" form class="form-horizontal">
Because form need to send by "POST" method, I understand that error!.
Here is validate part from ProfileController:validator
protected function validator(array $data) // copied from register controller
{
return Validator::make($data, [
'firstname' => 'required|max:255',
'lastname ' => 'required|max:255',
'email' => 'required|email|max:255|unique',
'phone' => 'integer',
'mobile' => 'integer',
]);
}
Here is ProfileController:createx part
I took it from registerController.
protected function createx(array $data) //copied from register controller
{ // was dublicate name "create"
return Profile::createx([ // changed to "createx"
'firstname' => $data['firstname'],
'lastname' => $data['lastname'],
]);
}
Here is profile model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Profile extends Model
{
//
protected $table = 'profiles';
protected $fillable = [
'firstname',
'lastname',
'email',
'phone',
'mobile',
// 'name', 'email', 'password',
];
protected $hidden = [
'status',
//'location',
];
}
Thanks to Alexey Mezenin DD() tip for troubleshoot
#MikroMika this data shows that you do not pass firstname and
lastname. Look at result of the dd($data); It should be something like
['firstname' => 'John', 'lastname' => 'Smith'] – Alexey Mezenin 20
mins ago
Now I am back to beginning,
Why form is not pass data by POST method ?
There is no createx() method in Eloquent. You defined it in a controller, but you're trying to use it with the model. Use create() method:
return Profile::create([
'firstname' => $data['firstname'],
'lastname' => $data['lastname'],
]);
Also, you've asked how to troubleshoot. Install Laravel Debugbar. Also, using dd() helper is really helpful:
dd(Profile::create([
'firstname' => $data['firstname'],
'lastname' => $data['lastname'],
]));
I am trying to validate an update user profile form, whereby the validation should check that the email doesn't exist already, but disregard if the users existing email remains.
However, this continues to return validation error message 'This email has already been taken'.
I'm really unsure where I'm going wrong. Otherwise, the update form works and updates perfectly.
HTML
{{ Form::text('email', Input::old('email', $user->email), array('id' => 'email', 'placeholder' => 'email', 'class' => 'form-control')) }}
Route
Route::post('users/edit/{user}', array('before' => 'admin', 'uses' => 'UserController#update'));
User Model
'email' => 'unique:users,email,{{{ $id }}}'
Your rule is written correctly in order to ignore a specific id, however, you'll need to update the value of {{{ $id }}} in your unique rule before attempting the validation.
I'm not necessarily a big fan of this method, but assuming your rules are a static attribute on the User object, you can create a static method that will hydrate and return the rules with the correct values.
class User extends Eloquent {
public static $rules = array(
'email' => 'unique:users,email,%1$s'
);
public static function getRules($id = 'NULL') {
$rules = self::$rules;
$rules['email'] = sprintf($rules['email'], $id);
return $rules;
}
}
You can accomplish this with the sometimes function of the validator
Something like:
$validator->sometimes('email', 'unique:users,email', function ($input) {
return $input->email == Input::get('email');
});
See http://laravel.com/docs/4.2/validation#conditionally-adding-rules for more info
Following are my codes:
Model:
class Slide extends \Eloquent {
// Add your validation rules here
public static $rules = [
'title' => 'required|between:3,100',
'image' => 'required',
'url' => 'url',
'active' => 'integer'
];
// Don't forget to fill this array
protected $fillable = ['title', 'image', 'url', 'active'];
}
Controller Update Method:
public function update($id)
{
$slide = Slide::find($id);
$validator = Validator::make($data = Input::all(), Slide::$rules);
if ($validator->fails())
{
return Redirect::back()->withErrors($validator)->withInput();
}
$slide->update($data);
return Redirect::route('admin.slides.index')
->with('message', 'Slide has been updated.')
->with('message-type', 'alert-success');
}
Route:
Route::group(array('prefix' => 'admin'), function() {
# Slides Management
Route::resource('slides', 'AdminSlidesController', array('except' => array('show')));
});
Form in View:
{{ Form::model($slide, array('route' => 'admin.slides.update', $slide->id, 'method' => 'put')) }}
#include('admin/slides/partials/form')
{{ Form::close() }}
Partial Form is simple form, not sure if I need to share it here or not. Let me know.
Error:
Edit page loads perfectly and populates data from db, but when I submit the edit form, I get following error:
Call to a member function update() on a non-object
The following line seems to be creating problems:
$slide->update($data);
I have searched over the internet for solution but nothing is working. Have tried composer dump_autoload, even tried doing everything from scratch in a new project, still same issue. :(
Help please!!
---- Edit ----
Just quickly tried following:
public function update($id)
{
$slide = Slide::find($id);
$slide->title = Input::get('title');
$slide->save();
return Redirect::route('admin.slides.index')
->with('message', 'Slide has been updated.')
->with('message-type', 'alert-success');
}
Now the error:
Creating default object from empty value
----- Solution: -----
The problem was with my form as suggested by #lukasgeiter
I changed my form to following at it worked like a charm:
{{ Form::model($slide, array('route' => array('admin.slides.update', $slide->id), 'method' => 'put')) }}
use $slide->save(); instead of $slide->update($data);
to update a model please read the laravel doc here
To update a model, you may retrieve it, change an attribute, and use the save method:
EX :
$user = User::find(1);
$user->email = 'john#foo.com';
$user->save();
The actual problem is not your controller but your form.
It should be this instead:
{{ Form::model($slide, array('route' => array('admin.slides.update', $slide->id), 'method' => 'put')) }}
This mistake causes the controller to receive no id. Then find() yields no result and returns null.
I recommend besides fixing the form you also use findOrFail() which will throw a ModelNotFoundException if no record is found.
$slide = Slide::findOrFail($id);
I'm still a student and still new with these frameworks
so I have two controllers in my routes:
Route::resource('homeworks', 'HomeworkController');
Route::resource('submithomeworks', 'SubmithomeworkController');
in views/Homework/show.blade.php, I have:
href="{{ URL::action('submithomeworks.create', $homeworks->id) }}"
so the URL will go from
http://localhost:8000/homeworks/1
to
http://localhost:8000/submithomeworks/create?1
so is there a way I can just store $homework->id which is just 1 in this situation to the submithomeworks table?
I tried this on the SubmithomeworksController
public function store()
{
$rules = array(
'homework_id' => 'required',
'homework_body' => 'required'
);
$submithomework = new Submithomework;
$submithomework->homework_id = Input::get('homework_id');
$submithomework->homework_body = Input::get('homework_body');
$submithomework->student_id = Auth::user()->id;
$submithomework->save();
Session::flash('message', 'Homework successfully added.');
return Redirect::to('homeworks');
}
but what do I do after that in the view? it won't store the homework_id says its still NULL
If you need to access a route parameter you can use the Route facade. For example:
Route::input('id');
You can check the Laravel Docs.