I have written a bunch of test cases for the registration form for a Laravel 5.3 project. One of the basic test cases is to insert fake data and check for the proper redirection. My test case code:
/**
* Check for the registration form
*
* #return void
*/
public function testNewUserRegister(){
// Generate a ranom name
$thisName = str_random(8);
// Genearte a random email
$thisEmail = str_random(8)."#google.com";
// Type some valid values
$this->visit('/register')
->type($thisName,'name')
->type($thisEmail,'email')
->type('password123','password')
->type('password123','password_confirmation')
->press('Register')
->seePageIs('/home');
}
Everything was working properly and no complaints from PHPUnit. But when I included the following method in my User model:
// Function to check for the adminship
public function isAdmin(){
// Check if the user is logged in
if(Auth::check()){
// Check if the user is admin
if(Auth::user()->isAdmin){
return true;
}
}
// Return false if not
return false;
}
The above test case testNewUserRegister fails and following is the error message:
There was 1 failure:
1) AuthTest::testNewUserRegister
A request to [http://localhost/home] failed. Received status code [500].
/var/www/html/project-css/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/InteractsWithPages.php:220
/var/www/html/project-css/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/InteractsWithPages.php:92
/var/www/html/project-css/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/InteractsWithPages.php:150
/var/www/html/project-css/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/InteractsWithPages.php:92
/var/www/html/project-css/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/InteractsWithPages.php:125
/var/www/html/project-css/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/InteractsWithPages.php:580
/var/www/html/project-css/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/InteractsWithPages.php:567
/var/www/html/project-css/tests/AuthTest.php:26
Caused by
ErrorException: Undefined property: App\User::$isAdmin in /var/www/html/project-css/app/User.php:36
Further, following is the database schema:
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->boolean('isAdmin')->default(false);
$table->boolean('hasAccess')->default(true);
$table->rememberToken();
$table->timestamps();
});
Not a duplicate here is why:
It's not due to the camel case as suggested. When included the following parameter the testing still fails:
public static $snakeAttributes = false;
Also modified the schema into camel case didn't solve my issue still the test fails.
You can go about this 2 different ways.
1. Change the migration
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->boolean('is_admin')->default(false);
$table->boolean('has_access')->default(true);
$table->rememberToken();
$table->timestamps();
});
2. Create an Accessor
In your User model create the following function:
public function getIsAdminAttribute()
{
return $this->isAdmin;
}
This will just return the value of the isAdmin column in the database.
I would personally go with the first option, it's a better naming convention for tables and keeps everything organized.
I would do this:
In your User model:
public function isAdmin(){
// this looks for an admin column in users table
return $this->admin;
}
Now add an admin field to your database:
php artisan add_admin_to_users_table
In your migration:
public function up()
{
Schema::table('users', function ($table) {
$table->boolean('admin')->default(0);
});
}
public function down(){
Schema::table('users', function ($table) {
$table->dropColumn('admin');
});
This should work properly.
Related
Before I get into what my issue is, here is my setup. (FYI I am stuck using Laravel 7.4 at the moment so SOS):
Applications Table
public function up()
{
Schema::create('applications', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});
}
Reports Table
public function up()
{
Schema::create('reports', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});
}
ApplicationReports Table (I know the naming convention is off, but this is how I have to do it for code base)
public function up()
{
Schema::create('applicationReports', function (Blueprint $table) {
$table->unsignedInteger('application_id')->nullable(false);
$table->unsignedInteger('report_id')->nullable(false);
});
}
Here is an example of the ApplicationReports table
application_id
report_id
200
2
Then I have a many to many relationship setup between the Applications and Reports tables like so:
Applications Model
public function reports() {
return $this->belongsToMany(Report::class, 'applicationReports');
}
Reports Model
public function applications() {
return $this->belongsToMany(Application::class, 'applicationReports');
}
In the ReportsController I have a method that will pull all the reports that are in the reports table and then return them, that method looks a little bit like the code below (pseudo coded some of it). But what I am trying to do is only add reports that are associated with applications to the list. When I try the code below doing $report->applications->has($report->id) its returning false and I can't for the life of me figure it out.
public function getReports() {
//Pseudo codeish right here, sorry.
$reports = gets all reports->with(['applications'])->orderBy('name')->get();
$reportsList = [];
foreach ($reports as $report) {
if ($report->applications->has($report->id)) {
$reportsList[] = $report;
}
}
return $reportList;
}
If I dd $report->applications the relationship is there and I can see it under #relations -> #attributes, any help would be appreciated!
The has function is very straight forward.
You can query your reports that only contains applications by doing:
$reports = Report::with('applications')->has('applications')->get();
return $reports;
in other way you can also use whereHas this will accepts Query Builder that you can pass through.
For example:
$reports = Report::with('applications')
->whereHas('applications', function(Builder $query) {
$query->orderBy('created_at');
})->get();
return $reports;
Laravel version: 7.0 Here is my table.
Schema::create('model_email_form', function (Blueprint $table) {
$table->id();
$table->string('model_type');
$table->unsignedBigInteger('model_id');
$table->unsignedBigInteger('email_id');
$table->unsignedBigInteger('form_id');
$table->timestamps();
});
Here is my Service model.
public function forms()
{
return $this->morphToMany(
Form::class,
'model',
'model_email_form',
'model_id',
'form_id'
);
}
public function emails()
{
return $this->morphToMany(
Email::class,
'model',
'model_email_form',
'model_id',
'email_id'
);
}
I inserted data in model_email_form table but when I get service model object, emails and forms have null object.
Can anyone help me?
From your question and comments:
There are Form, Email and Service. Forms can be associated with any number of different types of models. Emails can be associated with any number of different types of models. A Service can have many Forms and a Service can have many Emails.
Using that as the basis, this would be our schema:
Schema::create('forms', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name'); // as an example
...
$table->timestamps();
});
Schema::create('formables', function (Blueprint $table) {
$table->unsignedBigInteger('form_id'); // the id of the form
$table->unsignedBigInteger('formable_id'); // the associated model's id
$table->string('formable_type'); // The associated model's class name
});
Schema::create('emails', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('subject'); // as an example
...
$table->timestamps();
});
Schema::create('emailables', function (Blueprint $table) {
$table->unsignedBigInteger('email_id'); // the id of the email
$table->unsignedBigInteger('emailable_id'); // the associated model's id
$table->string('emailable_type'); // The associated model's class name
});
Schema::create('services', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name'); // as an example
...
$table->timestamps();
});
With that schema, we can create the following models with the following relationships:
class Form extends Model
{
public function services()
{
return $this->morphedByMany(Service::class, 'formable');
}
// Add the other morphedByMany relationships of forms
}
class Email extends Model
{
public function services()
{
return $this->morphedByMany(Service::class, 'emailable');
}
// Add the other morphedByMany relationships of emails
}
class Service extends Model
{
public function forms()
{
return $this->morphedToMany(Form::class, 'formable');
}
public function emails()
{
return $this->morphedToMany(Email::class, 'emailable');
}
}
I'm trying to give ability on user to see his orders. I have created relationships but when i (dd) the result of the function, the related model attributes are empty.
I don't know what is wrong.
Here is my buyer function
//Buyer Orders
public function myOrders()
{
$user = User::find(auth()->user()->id);
$user = $user->products();
dd($user);// related model attributes shows empty
return view('myOrders')->with(compact('user'));
}
and here is my user
public function products()
{
return $this->hasMany(Products_model::class);
}
public function orders()
{
return $this->hasMany(Order::class);
}
public function allOrdersBuyerSeller()
{
return $this->hasMany(OrderProduct::class);
}
products_model
public function orders()
{
return $this->belongsToMany('App\Order', 'order_product');
}
public function user()
{
return $this->belongsTo('App\User');
}
User Migration
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
Product 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->integer('category_id');
$table->string('image')->nullable();
$table->timestamps();
$table->bigInteger('seller_id')->unsigned()->index();
$table->foreign('seller_id')->references('id')->on('users')->onDelete('cascade');
});
}
I would like to see the attributes of the table like price, name, info, img and etc.
Barring the comments about your code, the reason you're not seeing the result of your products query is that you're not passing a closure to the query.
$user = $user->products();
Currently, $user is a QueryBuilder instance. Until you use a closure, like first(), get(), paginate(), etc, you won't be able to see the rows. Modify your code to the following:
$products = $user->products;
// OR
$products = $user->products()->get();
If you omit the (), it will load the relationship using products()->get(), unless already loaded.
Edit: You likely need to include foreign keys to your relationships as the Model name won't match:
User.php
public function products(){
return $this->hasMany(Product_model::class, "seller_id", "id");
}
Probably best to review the contents of the documentation for Relationships; https://laravel.com/docs/5.8/eloquent-relationships. There's a lot of incorrect practices going on with your naming, querying, etc.
I want to invalidate some inputs.I write these code in store method,but when I test my api on Postman give me 500 error.For example I don't give bodyfield in Body tab.
This is store function in my controller.
public function store(Request $request)
{
$validation=$this->getValidationFactory()->make($request->all(),[
'body'=>'required',
'image'=>'required|mimes:jpeg,png'
]);
if($validation->failed()){
return response()->json(['message'=>'Invalid Input Data!'],400);
}
$article=new Article();
$article->title=$request->title;
$article->body=$request->body;
$article->source=$request->source;
if($article->save()){
$article->categories()->sync($request->categories);
}
$name='article-'.$article->id.'.'.$request->file('image')->getClientOriginalExtension();
$request->file('image')->move(public_path('images'),$name);
$article->image= $name;
$article->save();
return response()->json(['message'=>'save successfully'],200);
}
This is migration file for create article table.
public function up()
{
Schema::create('articles', function (Blueprint $table) {
$table->increments('id');
$table->string('title')->nullable();
$table->text('body');
$table->boolean('is_active')->default(0);
$table->enum('status',['draft','completed','published'])->default('draft');
$table->timestamps();
});
}
And this is Postman screenshot.
im working on a laravel 5.5 project
and they told me to make role for every page
create edit update delete search softdelete
so i have created user table
this is the migration
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('user_name',40)->unique();
$table->string('user_email',40)->nullable()->unique();
$table->string('user_phone',40)->nullable()->unique();
$table->integer('user_department');
$table->string('password',60);
$table->rememberToken();
$table->timestamps();
$table->softDeletes();
});
}
and i have created model table this is the migration
public function up()
{
Schema::create('models', function (Blueprint $table) {
$table->increments('id');
$table->string('model_name',40)->unique();
$table->timestamps();
$table->softDeletes();
});
}
and i have created modelroles table
public function up()
{
Schema::create('modelroles', function (Blueprint $table) {
$table->increments('id');
$table->integer('model_id');
$table->integer('user_id');
$table->integer('create');
$table->integer('read');
$table->integer('update');
$table->integer('softdelete');
$table->integer('delete');
$table->integer('restore');
$table->integer('search');
$table->timestamps();
});
}
and i have created middlewaer called roleMiddleware
this is the code
use Closure;
class roleMiddleware
{
public function handle($request, Closure $next)
{
return $next($request);
}
}
so how can i connect them together in the middleware
what i want is to give every user role in every page create read update delete ect
mean check the url the request come from
and check the user id
and check the model id
and check the user_id and the model_id inside modelroles
and if he can create edit update delete on the model
i dont want to use packages like this
https://github.com/laravel-enso/RoleManager
or this
https://github.com/Zizaco/entrust
i dont want to connect users with global role
i want to give every user role for every controller