Laravel Eloquent, Multidimensional Relation Accessing - php

I have a 4 model Totally,
Project,
Board,
Task,
SubTask
Project -> hasMany -> Board
Project -> hasManyThrough -> Task
Board -> hasMany -> Task
Board -> hasManyThrough -> SubTask
Task -> hasMany -> SubTask
This is my Project Model,
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Project extends Model
{
use HasFactory, SoftDeletes;
public function priority()
{
return $this->belongsTo(Priority::class);
}
public function users()
{
return $this->belongsToMany(User::class);
}
public function boards()
{
return $this->hasMany(Board::class);
}
public function tasks()
{
return $this->hasManyThrough(Task::class, Board::class);
}
public function subTasks()
{
}
}
Board Model,
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Board extends Model
{
use HasFactory, SoftDeletes;
public function tasks()
{
return $this->hasMany(Task::class);
}
public function subTasks()
{
return $this->hasManyThrough(SubTask::class, Task::class);
}
}
Task Model,
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Task extends Model
{
use HasFactory, SoftDeletes;
public function subTasks()
{
return $this->hasMany(SubTask::class);
}
}
How can i access Project Subtasks with eloquent relation?

Related

How to Implement Many to Many Relationship with Different Database in Laravel 8?

I have 3 tables:
subdistrict (in database B)
users (in database A)
admin_area (in database A).
and now, i want to insert or display data for user with area. below is the code i have made:
Model User
<?php
namespace App\Models;
use App\Models\Marketplace\Subdistrict;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Facades\DB;
use Laravel\Sanctum\HasApiTokens;
use Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable, HasRoles, SoftDeletes;
public function areas()
{
return $this->belongsToMany(Subdistrict::class, 'admin_area', 'user_id', 'subdistrict_id');
}
}
Model Subdistrict
<?php
namespace App\Models\Marketplace;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Subdistrict extends Model
{
use HasFactory;
protected $connection = 'marketplace';
protected $table = 'subdistrict';
public function users() {
return $this->belongsToMany(User::class, 'admin_area', 'user_id', 'subdistrict_id');
}
}
admin_area table:
user_id
subdistrict_id
If I try to get the areas from user_id = 1, I get an error like below
How to fix it? or How to make pivot table with different database in laravel 8?
Barring any design considerations, you can try by including the database name in front of the table. I'm assuming that the databases are in the same server.
Try alternating database_a or database_b (I'm not 100% clear on how the relationship was created).
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable, HasRoles, SoftDeletes;
public function areas()
{
return $this->belongsToMany(Subdistrict::class, 'database_a.admin_area', 'user_id', 'subdistrict_id');
}
}

Laravel RelationShips eloquent Laravel with ( 5 tables )

I have 5 tables
Products
-- Categories
--- SubCategories
---- Marks
----- Suppliers
I want to know how to make relationship
I have Product Model structure with :
namespace App\Models\Products;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
use HasFactory;
protected $fillable = [.... ];
public function categorie(){
return $this->belongTo(categories::class);
}
public function sub_categorie(){
return $this->belongTo(sub_categorie::class);
}
public function marks(){
return $this->belongTo(marks::class);
}
public function suppliers(){
return $this->belongTo(suppliers::class);
}
}
i want to know if it's correct ?
Another Question how would be looks other Model relationships such Suppliers, Categories, SubCategories ...
It depends on the cardinality and the foreign_keys that are involved.
Products
-- Categories
--- SubCategories
---- Marks
----- Suppliers
The context that you gave me, I'm guessing that each table depends on the previous one as showed in the context that you gave. If so, then you can do the following:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Suppliers extends Model
{
protected $fillable = [.... ];
public function mark()
{
return $this->belongsTo(Mark::class);
}
}
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Marks extends Model
{
protected $fillable = [.... ];
public function subCategorie()
{
return $this->belongsTo(SubCategorie::class);
}
}
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class SubCategory extends Model
{
protected $fillable = [.... ];
public function categorie()
{
return $this->belongsTo(Categorie::class);
}
}
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Categorie extends Model
{
protected $fillable = [.... ];
public function categorie()
{
return $this->belongsTo(Product::class);
}
}
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
protected $fillable = [.... ];
}
For more in depht inormation, you can consult the section about relationshipts on laravel docs: https://laravel.com/docs/8.x/eloquent-relationships.
Please use the correct nomeclature of relationship's, instead of "categorie" write "category" in the function name, with that laravel will automaticaly recognise the foreign key.
Example:
public function category(){
return $this->belongTo(categories::class);
}
public function sub_category(){
return $this->belongTo(SubCategory::class);
}
public function mark(){
return $this->belongTo(Mark::class);
}
public function supplier(){
return $this->belongTo(Supplier::class);
}
Show me your models folder please if you have any problem .

Getting all the products in category

I'm using Laravel for a store project, I created the Models
Model : Category.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
public function products(){
return $this->hasMany(Product::class);
}
}
Model : Product.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
public function category(){
return $this->belongsTo(Category::class);
}
public function comments(){
return $this->hasMany(Comment::class);
}
}
Controller : ProductController.php
<?php
namespace App\Http\Controllers;
use App\Category;
use Illuminate\Http\Request;
class ProductController extends Controller
{
public function getAll($idCategory)
{
$roducts = Category::findOrFail($idCategory)->products();
}
}
I got this error:
Method 'findOrFail' not found in \App\Category
I have tried to solve this by changing to :
$roducts = Category::query()->findOrFail($idCategory)->products();
And I got this error:
Method 'products' not found in \Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Model|static|static[]
UPDATE
I'm using Laravel 5.7.24, and the errors are from the IDE (PhpStorm).

Use relationship with policy of another model

I am using Laravel v5.5.14.
I have an endpoint, for App\Message in routes/api.php:
Route::group(['middleware' => 'auth:api'], function() {
Route::put('messages/{message}', 'MessageController#update')->middleware('can:view,pet');
});
I want to apply the policy of can:view,pet which is defined in my PetPolicy.php here:
namespace App\Policies;
use App\User;
use App\Pet;
use Illuminate\Auth\Access\HandlesAuthorization;
class PetPolicy
{
use HandlesAuthorization;
public function view(User $user, Pet $pet)
{
return $user->pets()->where('pet_id', $pet->id)->exists();
}
}
Every App\Message has a App\Pet I declare that pets have many messages (one-to-many) relationship in my models. And every App\User can have many App\Pet so many-to-many.
app/Pet.php:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Pet extends Model
{
protected $fillable = ['name'];
public function messages()
{
// one-to-many hasMany belongsTo
return $this->hasMany('App\Message');
}
public function users()
{
// many-to-many belongsToMany "
return $this->belongsToMany('App\User');
}
}
app/Message.php:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Message extends Model
{
protected $fillable = ['body', 'kind'];
public function pet()
{
// one-to-many hasMany belongsTo
return $this->belongsTo('App\Pet');
}
}
app/User.php:
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
// ....
public function pets()
{
// many-to-many belongsToMany "
return $this->belongsToMany('App\Pet');
}
public function messages()
{
// one-to-many hasMany belongsTo
return $this->hasMany('App\Message');
}
}
However my policy is failing, it is always giving unauthorized. Did I make a mistake somewhere?
This is my app/AuthServiceProvider.php:
namespace App\Providers;
use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
protected $policies = [
'App\Pet' => 'App\Policies\PetPolicy',
'App\Message' => 'App\Policies\MessagePolicy'
];
public function boot()
{
$this->registerPolicies();
}
}
Thanks
Test it with this query :
namespace App\Policies;
use App\User;
use App\Pet;
use Illuminate\Auth\Access\HandlesAuthorization;
class PetPolicy
{
use HandlesAuthorization;
public function view(User $user, Pet $pet)
{
return User::where('id', $user->id)
->whereHas('pets', function ($query) use($pet) {
$query->where('id', $pet->id);
})
->exists();
}
}
Or just like this if you want :
return $user->pets->contains($pet->id);
Or like this :
return DB::table('pet_user')
->whereUserId($user->id)
->wherePetId($pet->id)
->count() > 0;

one to many relationship in Laravel5 is not working properly

I have a collection controller
looks like this
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Http\Middleware\Role;
use Illuminate\Support\Facades\Input;
use App\User;
use App\Invoice;
use Session;
use Validator;
class CollectionController extends Controller
{
/**
* Display a listing of the resource.
*
* #return Response
*/
public function __construct(){
$this->middleware('role:collector'); // replace 'collector' with whatever role you need.
}
public function getPayment($invoiceid){
$id =$invoiceid;
$invoice=Invoice::where('Id', $id)->with(['payments'])->get();
return View('collectionmodule/payment')->with(array('invoice'=>$invoice));
}
}
Then I have following models
Invoice
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Invoice extends Model
{
//
protected $table = 'event_invoice';
public function payments(){
return $this->hasMany('App\paymentrecieved','invoice_id');
}
public function comments(){
return $this->hasMany('App\comments','invoice_id');
}
}
Paymentrecieved
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class paymentrecieved extends Model
{
//
protected $table = 'paymentrecieved';
public function invoice(){
return $this->belongsTo('App\Invoice');
}
}
So for every Invoice there could be multiple payments .
So in My getPayment method I am writing Query like this .
$invoice=Invoice::where('Id', $id)->with(['payments'])->get();
Its getting me the Details from Invoice table . But its not getting me any Payment Details
Any one know why is this happening , According to me I have done the relationship properly
Thanks
You use Id (with uppercase) for the primary key, but the Invoice model is looking for the id (with lowercase).
You should define the primary key in the Invoice model like this:
protected $primaryKey = 'Id';

Categories