In my package I have come model with it own namespace
<?php
namespace Nosennij\LaravelCategoryMenuAndBreadcrumbs\models;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
public function scopeMain($query)
{
return $query->where('parent_id', 0);
}
public function subcategories(){
return $this->hasMany(Category::class, 'parent_id');
}
public function parent(){
return $this->belongsTo(Category::class, 'parent_id');
}
}
When I install package it will be good if I do not copy this model to app folder and do not change namespace to App. It will be better to extend this model from package imporing all parent methods. I try to do it next way
1) php artisan make:model Category
2) try to extend
namespace App;
use Illuminate\Database\Eloquent\Model;
use Nosennij\LaravelCategoryMenuAndBreadcrumbs\models\Category as ParentCategory;
class Category extends ParentCategory
{
public function __construct(array $attributes = [])
{
parent::__construct($attributes);
parent::boot();
}
//my own new methods or methods rewriting parent methods
}
How can I do it?
So in controller I want to use App\Category; and want to have acces to scopeMain, subcategories, parent methods from package model in vendor/nosennij/laravel-catmenubread/models/Category.php
Working variant- https://github.com/n-osennij/laravel-category
In your package move your models directory under src and capitalize the M e.g. src/Models/Category.php.
Then change the namespace in Category to be:
namespace Nosennij\LaravelCategoryMenuAndBreadcrumbs\Models;
Then in your Category class in your app directory change it to be:
use Nosennij\LaravelCategoryMenuAndBreadcrumbs\Models\Category as ParentCategory;
class Category extends ParentCategory
Related
this is my parent class which is a user class that has the main crud operations
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Repositories\UserRepository; //<----------- Here
class UserController extends Controller
{
protected $model;
public function index()
{
$users = $this->model::all();
return view('users.index', compact('users'));
}
}
this is my child class which is one of my user roles , it have the same crud operation but it need some more functinality
<?php
namespace App\Http\Controllers;
use App\Models\Teacher;
use App\Http\Controllers\UserController;
class TeacherController extends UserController
{
public function __construct()
{
$this->model = Teacher::class;
}
}
when I try to access the route i get this error : Class name must be a valid object or a string
at :
$users = $this->model::all();
Well, it seems my Laravel project used old cached routes. Just run
php artisan route:clear
from time to time before debugging anything.
Books model
namespace App;
use Illuminate\Database\Eloquent\Model;
class Books extends Model{
//
public $table = 'books';
}
My controller function.
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Books;
class HomeController extends Controller
{
public function addbooks()
{
$book = Books::all();
print_r ($book);
}
}
So the function addbooks, doesn't return anything.
I am using sqlite DB.
Attached is a screenshot of my SQL result.
php artisan tinker result.
Laravel's convention is plural table names by default. But when you write a class name (for Model) it should be singular. Try 'Book' as your class name.
I am writing system for players where I use Laravel freamwork (just for learn) and I have question for more experience developer. I have one function which return me some data to view. I use this function in 3 controllers (but i copy and paste this function to each Controller files) and can I just put this function in one file and then use it in these 3 controllers? How can I use the same function in diffrent controller without copy and past?
You can also use Traits to share methods, however, traits are more usually for describing characteristics and types.
You should create a utility class, or use consider an abstract controller class if this is desired.
You can create Base Controller:
<?php
namespace App\Http\Controllers;
class BaseController
{
protected $playersRepository;
public function __construct(PlayersRepository $playersRepository)
{
$this->playersRepository = $playersRepository;
}
}
Which is injected with a repository object:
<?php
namespace App\Http\Controllers;
class PlayersRepository
{
public function getPlayers()
{
return Player::all();
}
}
Which has a common method, that can be used in more than one extended controller:
Games
<?php
namespace App\Http\Controllers;
class Games extends BaseController
{
public function index()
{
return view('games', ['players' => $this->playersRepository->getPlayers()]);
}
}
Matches
<?php
namespace App\Http\Controllers;
class Matches extends BaseController
{
public function show()
{
return view('matches', [
'matches' => $matches,
'players' => $this->playersRepository->getPlayers()
]);
}
}
Create module (util) or override main Controller class.
I have two models: User and Form. The Form model has two belongsTo relationships:
class Form extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
public function manager_user()
{
return $this->belongsTo(User::class, 'manager_id');
}
}
manager_id is a nullable integer column.
Using artisan tinker, I try to assign a user as a manager to a form (using these methods):
$manager = App\User::findOrFail(1);
$form = App\Form::findOrFail(1);
$form->manager_user()->assign($manager);
but I get error:
$form->manager_user()->associate($gacek)
PHP Fatal error: Class 'App\App\User' not found in /var/www/html/test/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php on line 779
[Symfony\Component\Debug\Exception\FatalErrorException]
Class 'App\App\User' not found
What am I doing wrong? Why is the framework trying to search for App\App\User instead of App\User?
It's a fresh installation of Laravel 5.3.
EDIT
Full model files with namespaces:
Form model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Form extends Model
{
public function user(){
return $this->belongsTo("App\User");
}
public function manager_user(){
return $this->belongsTo("App\User", 'manager_id');
}
}
User model:
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
protected $fillable = [
'name', 'email', 'password', 'surname', 'login', 'sign'
];
protected $hidden = [
'password', 'remember_token',
];
public function forms(){
return $this->hasMany(Form::class);
}
}
You likely have a namespace resolution issue with the relative namespace class references App\User and App\Form with Laravel.
By default, this directory is namespaced under App and is autoloaded by Composer using the PSR-4 autoloading standard. You may change this namespace using the app:name Artisan command.
From Laravel Docs
Relative names always resolve to the name with namespace replaced by the current namespace. If the name occurs in the global namespace, the namespace\ prefix is stripped. For example namespace\A inside namespace X\Y resolves to X\Y\A. The same name inside the global namespace resolves to A.
From Namespace Resolution rules
Try either removing the App\ namespace declaration before your User and Form class references or prefix them with another \ to make them fully qualified.
As #Kevin Stitch suggested I had problem with relative namespaces.
In my Form model I adjusted the relationships to have absolute paths:
class Form extends Model
{
public function user(){
return $this->belongsTo("\App\User");
}
public function manager_user(){
return $this->belongsTo("\App\User", 'manager_id');
}
}
And then everything works fine (after restarting the artisan tinker).
I have this kind of database design
user_classes
- id
- user_id
- class_schedule_id
class_schedules
- id
- class_id
- date
classes
- id
- name
I am now in my UserClass.php Model File
public function classSchedule() {
return $this->belongsTo('\App\ClassSchedule');
}
public static function getClassByUser($user_id){
$user_class = self::where('user_id','=',$user_id)->with('classSchedule');
//other codes here...
}
My question here is that how can I access the name of the class in the class table since the user_classes table doesn't have a direct access to the class instead it should go through first to the class_schedules table.
I am not sure what Eloquent ORM Relationship should I use.
Your help will be greatly appreciated!
thanks! :)
First of all you will need to rename the third class, from class to something else. Then try this,
class user_classes Extends Eloquent {
function classSchedule() {
return $this->hasMany('Class_schedules','class_schedule_id');
}
}
class class_schedules Extends Eloquent {
function userClasses() {
return $this->belongsTo('user_classes', 'class_schedule_id');
}
function classSomething() {
return $this->hasOne('class_something','id');
}
}
class class_something Extends Eloquent {
function classSchedules() {
return $this->belongsTo('class_schedules', 'id');
}
}
Try and follow the naming conventions within Laravel, that will make your life easier down the road.
It uses the snake_cased version of the plural of your model name to define the table name automagically.
Besides that, when you have a relation with single or plural output, name your relation methods accordingly to describe what they do and what kind of output you can expect.
I prefer a dir /app/Models for the models, hence the namespace, you can change this to /app if that's where your models are.
<?php namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class UserClass extends Model
{
// only defined because laravel auto generates alphabetically
protected $table = 'user_classes';
public function user()
{
// given that User model was moved to app/Models, if not, use \App\User
return $this->belongsTo('\App\Models\User');
}
public function classSchedule()
{
return $this->belongsTo('\App\Models\ClassSchedule');
}
}
<?php namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class ClassSchedule extends Model
{
public function class()
{
return $this->belongsTo('\App\Models\Class');
}
}
<?php namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Class extends Model
{
public function classSchedules()
{
return $this->hasMany('\App\Models\ClassSchedule');
}
}
Now you can basically fetch all entries of UserClass for a particular user, with or without eager loading...
$userClasses = UserClass::where('user_id', $userId)->get();
$userClasses->map(function($userClass) {
echo $userClass->classSchedule->class;
});
More preferably you'll have a method userClasses() with a hasMany relation in your user model