I'm rather new to Laravel and am currently running Laravel 8.x on Windows 10. I've created a database table, model, factory and seeder for generating articles for an imaginary blog. (I'm imitating a tutorial on Laravel and Vue that I like on YouTube and also this article).
The article suggests verifying that everything works by going into php artisan tinker and executing the command:
Article::factory()->create();
When I do that, I get this message:
PHP Fatal Error: Class 'Article' not found in Psy Shell code on line 1
I have no idea what that's supposed to mean but I assume it's not happy with my code in some respect. I've looked at it as thoroughly as I can but don't see anything wrong based on the examples in the article. Could someone more knowledgeable in Laravel kindly eyeball this and tell me what I've done wrong? (For what it's worth, I tried User::factory()->create(); and it worked fine.)
Article.php is stored in app/Models and contains:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Article extends Model
{
use HasFactory;
protected $fillable = [
'title', 'body',
];
}
ArticleFactory.php is stored at database/factories and contains:
<?php
namespace Database\Factories;
use App\Models\Article;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
class ArticleFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* #var string
*/
protected $model = Article::class;
/**
* Define the model's default state.
*
* #return array
*/
public function definition()
{
return [
'title' => $this->faker->text(50),
'body' => $this->faker->text(200)
];
}
}
2020_11_30_034856_create_articles_table is stored at database/migrations and contains:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateArticlesTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('articles', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('body');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('articles');
}
}
Lastly, ArticlesTableSeeder.php is stored at database/seeders and contains:
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
class ArticlesTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
Article::factory()
->times(30)
->create();
}
}
Can anyone see why this code isn't working?
EDIT:
I tried Patricus' suggestion and it worked fine in tinker. However, when I tried php artisan db:seed, it failed. I got this error:
Seeding: Database\Seeders\ArticlesTableSeeder
Error
Class 'Database\Seeders\Article' not found
at C:\Laravel\larticles\database\seeders\ArticlesTableSeeder.php:16
12▕ * #return void
13▕ */
14▕ public function run()
15▕ {
➜ 16▕ Article::factory()
17▕ ->times(30)
18▕ ->create();
19▕ }
20▕ }
1 C:\Laravel\larticles\vendor\laravel\framework\src\Illuminate\Container\BoundMethod.php:36
Database\Seeders\ArticlesTableSeeder::run()
2 C:\Laravel\larticles\vendor\laravel\framework\src\Illuminate\Container\Util.php:40
Illuminate\Container\BoundMethod::Illuminate\Container\{closure}()
Tinker doesn't run in a namespace. While it tries to help you out with some things related to models, it can't autocorrect namespaces on static method calls.
Your model is \App\Models\Article. In tinker, you need to call:
\App\Models\Article::factory()->create();
Related
I found similar title and similar asked question on this website when I was researching to solve the problem. But none of posted answers helped me. This question might be duplicated but I could not solve the problem using existing questions on StackOverflow.
I'm trying to prevent access to users who are not logged in OR who are not member of "School" model!
In "web.php" file I used "middleware("auth")" to prevent access to users who are not logged in.
Now I created a "Policy" named "SchoolPolicy" to prevent access to users who are not member of "Schools" database/model.
When I call "view" method from SchoolPolicy, it prevents access for all authorized and unauthorized users!
I also checked and I realized "School" model returns "null" when I try to catch "user_id" foreign key from "schools" table.
The below piece of code is the way I created "Schools" table using Migration:
Schema::create('schools', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained();
$table->string('school_name');
$table->string('school_address')->nullable();
$table->string('school_email');
$table->string('school_phone')->nullable();
$table->string('url');
$table->longText('descriptions')->nullable();
$table->timestamps();
});
This is the route to view any school which is created by any user (URL can be dynamic)
Route::group(['middleware' => 'auth'], function () {
Route::get('/schools/{url}', [ViewSchool::class, 'index'])->name('yourschool.show');
});
And this is "School" model. I used php artisan make:model School command to create this model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Support\Facades\Auth;
class School extends Model{
use HasFactory;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'user_id',
'school_name',
'school_address',
'school_email',
'school_phone',
'url',
'descriptions'
];
}
In this section I created School Policy. However I used Laravel 8 but I also registered created Policy manually
SchoolPolicy
<?php
namespace App\Policies;
use App\Models\School;
use App\Models\User;
use Illuminate\Auth\Access\HandlesAuthorization;
class SchoolPolicy
{
use HandlesAuthorization;
/**
* Determine whether the user can view any models.
*
* #param \App\Models\User $user
* #return mixed
*/
public function viewAny(User $user)
{
//
}
/**
* Determine whether the user can view the model.
*
* #param \App\Models\User $user
* #param \App\Models\School $school
* #return mixed
*/
public function view(User $user, School $school)
{
return $user->id == $school->user_id;
}
}
In AuthServiceProvider.php I registered SchoolPolicy like this:
<?php
namespace App\Providers;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Gate;
use App\Models\User;
use App\Models\School;
use App\Policies\SchoolPolicy;
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* #var array
*/
protected $policies = [
School::class => SchoolPolicy::class
];
/**
* Register any authentication / authorization services.
*
* #return void
*/
public function boot()
{
$this->registerPolicies();
}
}
"ViewSchool.php" file where I want to use authorize method:
<?php
namespace App\Http\Controllers\Schools;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\User;
use App\Models\School;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Auth;
class ViewSchool extends Controller
{
public function index (School $school) {
$this->authorize('view', $school);
return view('layouts.viewschool');
}
}
I tried many ways to solve the problem, but none of them properly worked:
First Try:
public function index (School $school) {
$this->authorize('view', $school);
}
Second Try:
public function index () {
$this->authorize('view', School::class);
}
I even tried to print any output from School model but I receive "null":
public function index (School $school) {
dd($school->user_id);
}
I followed all tutorials on YouTube and official Laravel website, but in my examples I gave you, authorization doesn't work properly.
Please help me to solve this problem.
Thank you
I've been trying to heroku run php artisan migrate from AWS Cloud9 without any success. How can I fix this problem? I would appreciate it very much if someone could help me. Thanks a lot!
I get three errors, all of which are saying
SQLSTATE[42804]: Datatype mismatch: 7 ERROR: column "administered" cannot be cast automatically to type smallint
HINT: You might need to specify "USING administered::smallint"
The migration file in question is as follows:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class ChangeFilariasisMedicationsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::table('filariasis_medications', function (Blueprint $table) {
$table->dropColumn('administered');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('filariasis_medications', function (Blueprint $table) {
$table->smallInteger ('administered');
});
}
}
Here is the related model.
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
// 追加
use App\AdministeredDate;
use App\User;
use Illuminate\Notifications\Notifiable;
use App\Notifications\ReminderMail;
class FilariasisMedication extends Model
{
protected $fillable = [
'start_date',
'number_of_times',
'counter',
'administered'
];
protected $dates = [
'start_date',
];
use Notifiable;
/**
* この投薬スケジュールを所有するユーザ(Userモデルとの関係を定義)
*/
public function medication_user()
{
return $this->belongsTo(User::class);
}
/**
* この投薬スケジュールに属する投薬確定日(AdministeredDateモデルとの関係を定義)
*/
public function administered_date()
{
return $this->hasMany(AdministeredDate::class);
}
}
Current description of filariasis_medications table:
mysql> describe filariasis_medications;
enter image description here
You put a space before the parenthesis in your migration, remove it.
from $table->smallInteger ('administered');
to $table->smallInteger('administered');
I am trying to do password recovery in laravel, but after inserting an email to send the reset request, an error appears saying that password_resets doesn't exist.
I've already tried to migrate again but nothing works.
SQLSTATE[42P01]: Undefined table: 7 ERROR: relation "password_resets" does not exist
LINE 1: delete from "password_resets" where "email" = $1 ^ (SQL: delete from "password_resets" where "email" = blabla#gmail.com)
According to this, it seems that the command to generate the migration for password_resets no longer exists, you can try to create a new migration with this:
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreatePasswordResetsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('password_resets', function (Blueprint $table) {
$table->string('email')->index();
$table->string('token')->index();
$table->timestamp('created_at');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('password_resets');
}
}
In my case, I fixed the issue of the missing table by adding these two lines in AppServiceProvider.php.
Follow these steps:-
Open AppServiceProvider.php (Location: app/Providers/AppServiceProvider.php).
Add this line outside from classes use Illuminate\Support\Facades\Schema;
Add this line inside function boot() Schema::defaultStringLength(191);
Delete all tables from database.
Run this command php artisan migrate
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Schema;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* #return void
*/
public function register()
{
//
}
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
Schema::defaultStringLength(191);
}
}
I am using laravel 5.6 version, here is my Test model file
<?php
namespace App\Model\data\Models;
use Illuminate\database\Eloquent\Model;
class Test extends Model
{
protected $guarded = ['id'];
protected $table = 'tests';
/*
* Test - TestTranslation relation
* Test has many translations
*/
public function translations()
{
return $this->hasMany('App\Model\Data\Models\TestTranslation');
}
/*
* Test - Image relation
* Test can have an thumbnail
*/
public function thumbnails()
{
return $this->morphMany('App\Model\Data\Models\Image', 'type');
}
}
Here is my Image model
<?php
namespace App\Model\Data\Models;
use Illuminate\Database\Eloquent\Model;
class Image extends Model
{
protected $guarded = ['id'];
protected $table = 'images';
/*
* Image belongs to Post, Account, Comment
*/
public function type()
{
return $this->morphTo();
}
}
Here is my Database scheme for Images table:
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateImagesTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('images', function (Blueprint $table) {
$table->increments('id');
$table->string('path');
$table->enum('type', ['avatar', 'thumbnail', 'generic'])->default('generic');
$table->integer('type_id')->unsigned()->nullable();
$table->enum('type_type',[
"Account",
"Comment",
"Post",
"Skill",
"Test"
])->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('images');
}
}
In AppServiceProvider I linked 'Test' to my model file:
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\ServiceProvider;
use Laravel\Dusk\DuskServiceProvider;
use Illuminate\Database\Eloquent\Relations\Relation;
use App\Model\Data\Models\Account;
use App\Model\Data\Models\EmailChangeConfirmation;
use App\Model\Observers\Common\AccountObserver;
use App\Model\Observers\Common\EmailChangeConfirmationObserver;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
Schema::defaultStringLength(191);
Relation::morphMap([
'Account' => 'App\Model\Data\Models\Account',
'Comment' => 'App\Model\Data\Models\Comment',
'Post' => 'App\Model\Data\Models\Post',
'Skill' => 'App\Model\Data\Models\Skill',
'Test' => 'App\Model\Data\Models\Test'
]);
if(env('APP_ENV') != 'testing') {
Account::observe(AccountObserver::class);
EmailChangeConfirmation::observe(EmailChangeConfirmationObserver::class);
}
}
/**
* Register any application services.
*
* #return void
*/
public function register()
{
if ($this->app->environment('local', 'testing')) {
$this->app->register(DuskServiceProvider::class);
}
}
}
As you can see, I have more morhpMany types, and all of them works fine. But for some reason, this Test relation that I added recently always returns an empty collection, even tough I am sure that test has thumbnails. Cause:
in this screenshot, I have records in database that each test has two images. Their ID matches ids of created tests and type is "Test". I tried to clear all caches, run composer dump-autoload but none of them helped.
Maybe someone can help identify what is wrong here? Because as I said before other types as Post, Account works fine.
I am trying to make a chatbox using Laravel and Vue.js. I am following this online tutorial. I have followed almost every step to a tee and I cannot tell why I am not getting the desired result. Here is what I have done thus far:
I have created a User model and a Message model with the correct table columns and migrations. In the User model I established a hasMany relationship with the Message model. In the Message model, I established a belongsTo relationship with User.
When I go into tinker, I can do:
factory(App\User::class)->create()
just fine, like the guy in the tutorial can do. However when I try to do:
App\User::find(4)->messages()->created(['message'=> "Hello from Sharon"])
I get this error:
BadMethodCallException with message 'Method Illuminate\Database\Query\Builder::messages does not exist.'
Here is my code:
User Model:
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password','api_token',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function messages()
{
return $this->hasMany(Message::class);
}
}
Message Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Message extends Model
{
protected $fillable = ['message'];
public function user()
{
return $this->belongsTo(User::class);
}
}
Message Migration:
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateMessagesTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('messages', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
$table->text('message');
$table->integer('user_id')->unsigned();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('messages');
}
}
If you could let me know what I am doing wrong, I would really appreciate it. Thanks.
Restart the php artisan tinker and re-run your code. It works:)
Seems you are getting this error:
BadMethodCallException with message 'Method Illuminate\Database\Query\Builder::created does not exist.'
To save models to relationships, use create method, but not created method, for example:
App\User::find(4)->messages()->create(['message'=>'Hello from Sharon']);
instead of App\User::find(4)->messages()->created(['message'=> "Hello from Sharon"])
try to use
App\User::find(4)->messages()->create(['message'=> "Hello from Sharon"])
or
App\User::find(4)->messages()->save(['message'=> "Hello from Sharon"])