I'm studing about Repository Design Pattern in Laravel and I'm using https://github.com/andersao/l5-repository to do it.
I think i install success in my project . But when i run code with repository i have some problem
SQLSTATE[42S02]: Base table or view not found: 1146 Table
'test.nhanviens' doesn't exist (SQL: select * from nhanviens)
Table in my database is Nhanvien not Nhanviens
Here in my code
NhanvienRepository.php
<?php
namespace App\Repositories;
use Prettus\Repository\Contracts\RepositoryInterface;
/**
* Interface NhanvienRepository
* #package namespace App\Repositories;
*/
interface NhanvienRepository extends RepositoryInterface
{
//
}
NhanvienRepositoryEloquent.php
<?php
namespace App\Repositories;
use Prettus\Repository\Eloquent\BaseRepository;
use Prettus\Repository\Criteria\RequestCriteria;
use App\Repositories\NhanvienRepository;
use App\Entities\Nhanvien;
use App\Validators\NhanvienValidator;
/**
* Class NhanvienRepositoryEloquent
* #package namespace App\Repositories;
*/
class NhanvienRepositoryEloquent extends BaseRepository implements NhanvienRepository
{
/**
* Specify Model class name
*
* #return string
*/
public function model()
{
return Nhanvien::class;
}
/**
* Boot up the repository, pushing criteria
*/
public function boot()
{
$this->pushCriteria(app(RequestCriteria::class));
}
}
DataController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\nhanvien;
use App\Repositories\NhanvienRepository;
class DataController extends Controller
{
protected $repository;
public function __construct(NhanvienRepository $repository){
$this->repository = $repository;
}
public function DanhSach(){
var_dump($this->repository->all());
}
}
from App\Nhanvien.php Add this variable to the class:
protected $table = 'nhanvien';
Explanation: The "snake case", plural name of the class will be used as the table name unless another name is explicitly specified. So, in this case, Eloquent will assume the nhanvien model stores records in the nhanviens table.
As stated in the official Eloquent documentation you need to specifically set the table name in your Model definition. That is, in your App\Nhanvien.php file set the following:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Nhanvien extends Model
{
/**
* The table associated with the model.
*
* #var string
*/
protected $table = 'Nhanvien';
}
or use
protected $table = 'nhanvien';
instead if your table name is full lowercase.
Check your migration file, maybe you are using Schema::table, like this:
Schema::table('table_name', function ($table) {
// ... });
If you want to create a new table you must use Schema::create:
Schema::create('table_name', function ($table) {
// ... });
See the Laravel migration documentation for more information.
If you are using Schema::create then please provide the contents of your migration file.
In my case, I've got rid of similar error by executing the command
php artisan config:cache
Related
I create model to another path
namespace Core\Entity;
use Core\Base\BaseEntity;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class News extends BaseEntity
{
use HasFactory;
And This is My seeder
use Core\Entity\News;
class NewsSeeder extends Seeder
{
public function run()
{
News::factory(500)->create();
}
And This is my factory
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* #extends \Illuminate\Database\Eloquent\Factories\Factory<\Core\Entity\News>
*/
class NewsFactory extends Factory
{
/**
* Define the model's default state.
*
* #return array<string, mixed>
*/
public function definition()
{
return [
];
}
}
Problem Is it Can not Find path of Factory , gives me like this ERROR
Class "Database\Factories\Core\Entity\NewsFactory" not found
How I can solve this problem?
Update your namespace in Factory class:
namespace Database\Factories;
to
namespace Database\Factories\Core\Entity;
And run composer dump-autoload
I have a many to many relationship between two models:
User
namespace App\Models;
class User extends Model
{
use HasApiTokens, Notifiable,hasFactory;
/**
* The attributes that are mass assignable.
*
* #var array
*/
];
}
Notification
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Notification extends Model
{
/**
* #var array
*/
protected $guarded = ['id'];
use HasFactory;
/**
* #return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function user()
{
return $this->belongsTo(User::class);
}
}
I created a factory for each model and a Seeder which calls the two factories in order to create users and attach notifications to each one of them.
NotificationUserSeeder:
<?php
namespace Database\Seeders;
use App\Models\Notification;
use App\Models\User;
use Illuminate\Database\Seeder;
class MockNotificationUser extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
}
}
I am getting this error when running db:seed:
Call to undefined method Illuminate\Notifications\Notification::getConnectionName()
Since you have named model name as Notification .And while importing in seeder class ,it look like you have imported
use Illuminate\Notifications\Notification;
instead of
use App\Models\Notification;
Updated
The issue is with User model due to conflict in model name and Illuminate Notification facade's. Notification facade not used in User model so better to remove notification import. Suppose if you are using Notification illuminate then you can use as alias any one of the imports
I get the title error when I run command:
php artisan db:seed
My screenshot:
I have no idea where this problem comes from. I was searching for code examples and solution but I haven't found anything :(
ArticlesTableSeeder.php
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
// use Laracasts\TestDummy\Factory as TestDummy;
class ArticlesTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
factory(App\Models\Article::class, 30)->create();
}
}
ArticleFactory.php
<?php
namespace Database\Factories;
use App\Models\Model;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
class ModelFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* #var string
*/
protected $model = App\Models\Article::class;
/**
* Define the model's default state.
*
* #return array
*/
public function definition()
{
return [
'title' => $faker->text(50),
'body' => $faker->text(200)
];
}
}
DatabaseSeeder.php
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* #return void
*/
public function run()
{
$this->call(ArticlesTableSeeder::class);
}
}
Thank you in advance for your help!
In laravel 8 the default route namespace was removed.
Try to change:
ArticlesTableSeeder.php:
factory(App\Models\Article::class, 30)->create();
to:
\App\Models\Article::factory()->count(30)->create();
ArticleFactory.php:
protected $model = App\Models\Article::class;
to:
protected $model = \App\Models\Article::class;
and you will probably have to change:
'title' => $faker->text(50),
'body' => $faker->text(200)
to:
'title' => $this->faker->text(50),
'body' => $this->faker->text(200)
All suggestions that were mentioned here are correct.
Sometimes running composer require laravel/legacy-factories might fix your problem if you're using Laravel 8.
Also, in case you get an error that says Class 'Database\Factories\ArticleFactory' not found
then make sure you have class ArticleFactory extends Factory and not ModalFactory.
And make sure you're using HasFactory in the Article Model like here.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Article extends Model
{
use HasFactory;
}
For more info: Laravel 8 Modal Factories
Try to change
factory(App\Models\Article::class, 30)->create();
to
App\Models\Article::factory()->count(30)->create();
ArticlesTableSeeder.php
<?php
namespace Database\Seeders;
use App\Models\Article;
use Illuminate\Database\Seeder;
class ArticlesTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
Article::factory()->times(30)->create();
}
}
ArticleFactory.php
<?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)
];
}
}
If you are using version 8 of laravel, look at the upgrade guide.
"Laravel's model factories feature has been totally rewritten to support classes and is not compatible with Laravel 7.x style factories. However, to ease the upgrade process, a new laravel/legacy-factories package has been created to continue using your existing factories with Laravel 8.x. You may install this package via Composer:
composer require laravel/legacy-factories"
https://laravel.com/docs/8.x/upgrade#seeder-factory-namespaces
change
factory(App\Models\Article::class, 30)->create();
to
\App\Models\Article::factory(30)->create();
I'm facing the same issue when I realized my model was not using the HasFactory trait.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
use HasFactory;
/**
* The table associated with the model.
*
* #var string
*/
protected $table = 'categories';
}
So make sure this trait is being used by your model.
If you are using version 8 of laravel you can directory use:
use App\Models\Article;
Article::factory()->count(30)->create();
composer require laravel/legacy-factories
php artisan db:seed
I know there are so many answer, but I cannot really solve this.
I did follow this answer (How to make a REST API first web application in Laravel) to create a Repository/Gateway Pattern on Laravel 5.7
I have also the "project" on github, if someone really kindly want test/clone/see : https://github.com/sineverba/domotic-panel/tree/development (development branch)
App\Interfaces\LanInterface
<?php
/**
* Interface for LAN models operation.
*/
namespace App\Interfaces;
interface LanInterface
{
public function getAll();
}
App\Providers\ServiceProvider
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Schema;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
/**
* Solve the "Key too long" issue
*
* #see https://laravel-news.com/laravel-5-4-key-too-long-error
*/
Schema::defaultStringLength(191);
}
/**
* Register any application services.
*
* #return void
*/
public function register()
{
$this->app->register(RepositoryServiceProvider::class);
}
}
App\Providers\RepositoryServiceProvider
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class RepositoryServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->bind(
'app\Interfaces\LanInterface', // Interface
'app\Repositories\LanRepository' // Eloquent
);
}
}
App\Gateways\LanGateway
<?php
/**
* The gateway talks with Repository
*/
namespace App\Gateways;
use App\Interfaces\LanInterface;
class LanGateway
{
protected $lan_interface;
public function __construct(LanInterface $lan_interface) {
$this->lan_interface = $lan_interface;
}
public function getAll()
{
return $this->lan_interface->getAll();
}
}
App\Repositories\LanRepository
<?php
/**
* Repository for LAN object.
* PRG paradigma, instead of "User"-like class Model
*/
namespace App\Repositories;
use App\Interfaces\LanInterface;
use Illuminate\Database\Eloquent\Model;
class LanRepository extends Model implements LanInterface
{
protected $table = "lans";
public function getAll()
{
return 'bla';
}
}
I did add also App\Providers\RepositoryServiceProvider::class, in providers section of config\app.php
This is finally the controller (I know that it is not complete):
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Gateways\LanGateway;
class LanController extends Controller
{
private $lan_gateway;
/**
* Use the middleware
*
* #return void
*/
public function __construct(LanGateway $lan_gateway)
{
$this->middleware('auth');
$this->lan_gateway = $lan_gateway;
}
/**
* Display a listing of the resource.
*
* #return \Illuminate\Contracts\Support\Renderable
*/
public function index()
{
$this->lan_gateway->getAll();
return view('v110.pages.lan');
}
}
And the error that I get is
Target [App\Interfaces\LanInterface] is not instantiable while building [App\Http\Controllers\LanController, App\Gateways\LanGateway].
I did try:
php artisan config:clear
php artisan clear-compiled
I think #nakov might be right about it being case-sensitive. I don't believe PHP itself cares about upper/lowercase namespaces, but the composer autoloader and the Laravel container use key->value array keys, which do have case-sensitive keys, to bind and retrieve classes from the container.
To ensure the names always match, try using the special ::class constant instead, like this:
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\Repositories\LanRepository;
use App\Interfaces\LanInterface;
class RepositoryServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->bind(
LanInterface::class,
LanRepository::class
);
}
}
In my case i forgot to enlist the provider to confit/app.php that's why the error.
Clear the old boostrap/cache/compiled.php:
php artisan clear-compiled
Recreate boostrap/cache/compiled.php:
php artisan optimize
Let's say I have a UserController class and I'm importing the App\User class with use. Inside, there is a show() method that receieves an instance of User.
namespace App\Http\Controllers;
use App\User;
class UserController extends Controller
{
/**
* Show user info
*
* #param User $user
* #return Illuminate\Http\JsonResponse
*/
public function show(User $user)
{
// Do something...
}
}
Is it recommended to add the fully qualified name of User in PHPDoc even if I'm importing the class with use?
Use FQN if there are no use statement, as it would be recognized as a different class, in Your case as \JsonResponse which is not imported.
As for User class, use short name.
It is more convenient to import class with use statement and write short name in docblock.
Also class aliases can be used, for instance:
namespace App\Http\Controllers;
use App\User;
use Illuminate\Http\JsonResponse as Response;
class UserController extends Controller
{
/**
* Show user info
*
* #param User $user
* #return Response
*/
public function show(User $user)
{
// Do something...
}
}