I want to validate if the user is associated with the order in the request validation.
Order Migration:
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id')->nullable();
...
$table->timestamps();
$table->softDeletes();
User Table:
$table->bigIncrements('id');
$table->string('name');
$table->string('email')->unique();
$table->timestamps();
I have manually created a function to check if the order is associated with the user
public function checkIfOrderIsAssociatedWithTheUser(Request $request){
$checkExistsStatus = Order::where('id',$request->order_id)->where('user_id', $request->user_id)->exists();
return $checkExistsStatus;
}
When I need to check the associate, I have to call this function like:
$this->validate($request, [
'order_id' => 'required|exists:orders,id',
'user_id' => 'required|exists:users,id'
]);
$checkExistsStatus = $this->checkIfOrderIsAssociatedWithTheUser($request);
if(!$checkExistsStatus){
return redirect()->back()->withErrors([
'Order and user is not linked'
]);
}else{
...
}
I tried to create a new rule: CheckAssociationBetweenOrderAndUser but I am unable to pass the user_id to it.
$this->validate($request, [
//unable to pass user_id
'order_id' => ['required', new CheckAssociationBetweenOrderAndUser()]
]);
Is there any better way to validate the association check by creating a custom new rule? Or this is the only way to check the association?
Creating a custom rule was a good attempt. You can pass the $request as param in the constructor like
$this->validate($request, [
'field' => ['required', new CustomRule ($request)]
]);
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
use Illuminate\Http\Request;
class CustomRule implements Rule
{
protected $request;
public function __construct(Request $request)
{
$this->request = $request;
}
...
}
Related
please I am new to Laravel, I want to use Laravel API Resource to store database inside database.
I have 3 Tables
Users
Category
Category_User (this is a pivot table)
In my Controller (OnboardsControllers), I have this to store data
public function store(Request $request)
{
$category_user = Category_User::firstOrCreate(
[
'user_id' => $request->user()->id,
'category_id' => $request->$category->id,
],
);
return new CategoryUserResource($category_user);
}
In my CategoryUserResource I have this
public function toArray($request)
{
return [
'user_id' => $this->user_id,
'category_id' => $this->category_id,
'created_at' => (string) $this->created_at,
'updated_at' => (string) $this->updated_at,
];
In my Pivot Table, I have this
public function up()
{
Schema::create('category_user', function (Blueprint $table) {
$table->bigIncrements('id');
$table->integer('category_id')->unsigned();
$table->integer('user_id')->unsigned();
$table->timestamps();
});
}
In my model, I added this
protected $fillable = [
'user_id', 'category_id',
];
In my route/api
Route::post('/category_user', 'OnboardsController#onboardupdate');
I believe the error is here
'user_id' => $request->user()->id,
When I removed it, it didn't returned any error
When I tried to save to my database using Postman to test, it not saving. Please, I don't know what I am doing wrong.
Thanks
To be honest, you do not need a model Category_User (but you need a table).
In Laravel a more concise approach is used:
public function store(Request $request)
{
$user = User::find($request->input('user_id'));
$user->categories()->attach($request->input('category_id'));
}
Also I'm not sure if you have declared a method categories() in model User:
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function categories()
{
return $this->belongsToMany(Category::class);
}
}
I also strongly doubt the existence of method user() of class Request.
If the request parameter has a name category_id, then you need to access it like this:
$request->input('category_id');
I'm getting this errorarray_map(): Argument #2 should be an array when a user trying to create a product
I changed my code from this solutions How to make each authenticated user only see their own product, and now it gives me that error.
ProductController
class productController extends Controller
{
public function index(Request $request)
{
$userId = $request->user()->id;
$products = products_model::where('user_id', $userId)->get();
return view('seller.product.index',compact('products'));
}
public function create()
{
return view('seller.product.create');
}
public function seller()
{
$products=products_model::all();
return view('seller.product.index',compact('products'));
}
public function store(Request $request)
{
$formInput=$request->except('image');
$this->validate($request, [
'pro_name'=> 'required',
'pro_price'=> 'required',
'pro_info'=> 'required',
'user_id' => \Auth::id(),
'image'=>'image|mimes:png,jpg,jpeg|max:10000'
]);
$image=$request->image;
if($image){
$imageName=$image->getClientOriginalName();
$image->move('images', $imageName);
$formInput['image']=$imageName;
}
products_model::create($formInput);
return redirect()->back();
}
public function show($id)
{
//
}
public function edit($id)
{
//
}
public function update(Request $request, $id)
{
//
}
public function destroy($id)
{
$userId = $request->user()->id();
$deleteData=products_model::where('user_id', $userId)->findOrFail($id);
$deleteData->delete();
return redirect()->back();
}
}
Products_model
class products_model extends Model
{
protected $table='products';
protected $primaryKey='id';
protected $fillable= ['user_id','pro_name','pro_price','pro_info','image','stock','category_ id'];
}
Products table
class CreateProductsTable extends Migration
{
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('pro_name');
$table->integer('pro_price');
$table->text('pro_info');
$table->integer('stock');
$table->string('image')->nullable();
$table->timestamps();
$table->bigInteger('user_id')->unsigned()->index();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});
}
public function down()
{
Schema::dropIfExists('products');
}
}
After updating my code now am getting this errorSQLSTATE[HY000]: General error: 1364 Field 'user_id' doesn't have a default value (SQL: insert intoproducts(pro_name,pro_price,stock,pro_info,i`
Change your validate function. Instead of use $this->validate(),
use $request->validate() method:
$request->validate([
'pro_name'=> 'required',
'pro_price'=> 'required',
'pro_info'=> 'required',
'user_id' => 'required|integer',
'image'=>'image|mimes:png,jpg,jpeg|max:10000'
]);
If the validation rules pass, your code will keep executing normally; however, if validation fails, an exception will be thrown and the proper error response will automatically be sent back to the user.
Another solution:
Add
use Validator;
to your class.
$validator = Validator::make($request->all(), [
'pro_name'=> 'required',
'pro_price'=> 'required',
'pro_info'=> 'required',
'user_id' => 'required|integer',
'image'=>'image|mimes:png,jpg,jpeg|max:10000'
]);
if($validator->fails()){
//Validation does not pass logic here
}else{
//
}
One more:
Create a form request, with
php artisan make:request RequestName
The file will be created in app\Http\Requests directory.
Within the file, add your rules to the rules method:
public function rules()
{
return [
'pro_name'=> 'required',
'pro_price'=> 'required',
'pro_info'=> 'required',
'user_id' => 'required|integer',
];
}
Change the authorize method, to return true:
public function authorize()
{
return true;
}
In your store method, swap the Request $request with RequestName $request.
Now you don't need to validate the $request inside store method. It will go to store only if the validation succeed;
Your store method now should looks like
public function store(RequestName $request)
{
$formInput=$request->except('image');
$image=$request->image;
if($image){
$imageName=$image->getClientOriginalName();
$image->move('images', $imageName);
$formInput['image']=$imageName;
}
products_model::create(array_merge(
$formInput, ['user_id' => Auth::user()->id]
));
return redirect()->back();
}
Dont forget to use App\Http\Requests\RequestName
If validation fails, a redirect response will be generated to send the user back to their previous location. The errors will also be flashed to the session so they are available for display. If the request was an AJAX request, a HTTP response with a 422 status code will be returned to the user including a JSON representation of the validation errors.
You can learn more about request validation here.
[EDIT]
I change the users_id rule to user_id, to match with your foreign key name.
I think you made a typo here when you asked the question.
Hope it helps.
I am using Laravel Framework 5.5.22.
I am having users and tasks in my db. My tasks have the following schema:
Schema::create('tasks', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->integer('user_id')->unsigned();
$table->timestamps();
});
My users model looks like the following
class User extends Authenticatable
{
use Notifiable;
protected $fillable = [
'name', 'email', 'password',
];
protected $hidden = [
'password', 'remember_token',
];
public function task()
{
return $this->hasMany('App\Task');
}
}
I would like to store the task from a user in the database. See below the store method I have tried:
public function store(Request $request)
{
$this->validate($request, [
'newTaskName' => 'required|min:3|max:190',
]);
Auth::user()->task()->Create($request->all()); //here I get the error
Session::flash('success', 'New task has been successfully added.');
return redirect()->route('tasks.index');
}
However, I get the following error at this line Auth::user()->task()->Create($request->all());:
Illuminate\Database\Eloquent\MassAssignmentException _token
Any suggestions why the request is not safed properly?
Try with DB
$insertData = [
"name" => $request->name,
"user_id" => \Auth::id()
];
DB::table('tasks')->insert($insertData);
OR if you have model created as Task
$task = new Task($insertData);
$task->save();
Use the ->except() method instead of all():
Auth::user()->task()->create($request->except('_token'));
at Task Model add this line :
protected $guarded = ['_token'];
I'm looking to add a field on my registration page using Laravel Auth.
The basic user table contain the name, email, password.
I want to add an right field.
So I've eddited the create_users_table.php migration file to
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->integer('right_id');
$table->rememberToken();
$table->timestamps();
});
}
and my registercontroller.phpto
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'right_id' => 0,
'password' => bcrypt($data['password']),
]);
}
But it doesn't works. I still have this error about right_id. Seem that the value is not send to the database.
Any fix/help?
Thanks
Have you specify your right_id in User model class like the code sample below? If you forget to declare the additional field in the $fillable, the value wont save into database.
namespace App;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password', 'right_id'
];
}
Use like this
$data['right_id'] = 0;
$data['password'] = bcrypt($data['password']);
return User::create($data);
on your registercontroller.php try to use
'right_id' => '0', instead of 'right_id' => 0,
If you just want to have '0' as a default value for 'right_id' you can also specify it on your creat_users_table.php like this
$table->integer('right_id')->default(0);
Then redo the migration
I'm trying to add a field to the users table created by Laravel 5. I've modified the migration to add that field:
class CreateUsersTable extends Migration
{
public function up()
{
Schema::create('users', function(Blueprint $table)
{
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password', 60);
$table->string('my_new_field'); // Added this field
$table->rememberToken();
$table->timestamps();
});
}
...
}
I'm using the default authentication system provided by Laravel. Whenever a new user registers, I need my_new_field to be set to some value. How (and where) do I do that?
The AuthController handles the authentication process. It uses the trait AuthenticatesAndRegistersUsers where the postRegister() function handles the registration requests. But where are the actual values inserted?
The create() method in App\Services\Registrar is responsible for creating a new User instance. I added the field to this function:
/**
* Create a new user instance after a valid registration.
*
* #param array $data
* #return User
*/
public function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
'my_new_field' => 'Init Value'
]);
}
According to the documentation,
To modify the form fields that are required when a new user registers
with your application, you may modify the App\Services\Registrar
class. This class is responsible for validating and creating new users
of your application.
The validator method of the Registrar contains the validation rules
for new users of the application, while the create method of the
Registrar is responsible for creating new User records in your
database. You are free to modify each of these methods as you wish.
The Registrar is called by the AuthController via the methods
contained in the AuthenticatesAndRegistersUsers trait.
UPDATE Feb 03, 2016
Laravel 5.2
The settings found in the app/Services/Registrar.php file have been moved to app/Http/Controllers/Auth/AuthController.php
I also had to make this field fillable in the User model:
class User extends Model implements AuthenticatableContract, CanResetPasswordContract
{
...
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = ['name', 'email', 'password', 'my_new_field'];
...
}
Simply add a default value to the field like that:
class CreateUsersTable extends Migration {
public function up()
{
Schema::create('users', function(Blueprint $table)
{
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password', 60);
$table->string('my_new_field')->default('init_value'); // Added this field
$table->rememberToken();
$table->timestamps();
});
}
...
}
Alternativeley, just use a new migration to add the column in case the create migration has already been executed:
class AddMyNewFieldToUsersTable extends Migration {
public function up()
{
Schema::table('users', function($table) {
$table->string('my_new_field')->default('init_value'); // Added
});
}
public function down()
{
Schema::table('users', function($table) {
$table->dropColumn('my_new_field');
});
}
}
If you do not wish to use db defaults, you could also set this value in the controller within the store method:
public class UsersController extends BaseController {
// ...
public function store(Request $request) {
$user = new User;
$user->fill($request->all());
$user->my_new_field = 'init_value';
$user->save();
// return whatever
}
}
EDIT
Given the Information you gave in the comments here is a little guidance:
In the AuthController (/app/Http/Controllers/Auth/AuthController.php) add the following method (this overrides the default of the AuthenticatesAndRegistersUsers-trait which can be found here)
public function postRegister(Request $request)
{
$validator = $this->validator($request->all());
if ($validator->fails())
{
$this->throwValidationException(
$request, $validator
);
}
$user = $this->create($request->all()); // here the values are inserted
$user->my_new_field = 'init_value'; // here would be the place to add your custom default
$user->save(); // maybe try to do all that in a single transaction...
Auth::login($user);
return redirect($this->redirectPath());
}
Im not quite sure if this works out of the box, but it should get you startet.
Open the trait located at (for Laravel 5.2 AuthController)
/vendor/laravel/framework/src/Illuminate/Foundation/Auth/AuthenticatesAndRegistersUsers.php
Here you can easily find interesting methods that will responsible for login and register user.
These are
getRegister() // responsible for showing registration form
postRegister() // responsible for processing registration request
getLogin() // responsible for showing login form
postLogin() // responsible for authentication user
These methods are called every time, when you will access specific route (auth/register or auth/login) i.e User registration & User login
Hope this will clear some concepts !!