Specifying morphTo method target id column - laravel

Is there a way to specify target id column on morphTo method?
I'll give an example which is in documentation for laravel:
Post - Id, text
Video - Id, url
Comment - Id, text, commentable_id, commentable_type
But what if Ids on post and video were renamed to custom_id? How would I set up my eloquent model then? Thanks.
Edit:
I still don't get it here is the complete code:
Table structure:
comments - id, text, commentable_id, commentable_type, user_id
posts - custom_id, text
videos - custom_id, url
users - id, name, email, password,...
Comment model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
public function commentable()
{
return $this->morphTo();
}
}
Video model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Video extends Model
{
public function comments()
{
return $this->morphMany('App\Comment', 'commentable', 'commentable_type', 'commentable_id', 'custom_id');
}
}
Post model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
public function comments()
{
return $this->morphMany('App\Comment', 'commentable', 'commentable_type', 'commentable_id', 'custom_id');
}
}
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',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function comments()
{
return $this->hasMany('App\Comment');
}
}
TestController:
<?php
namespace App\Http\Controllers;
use App\User;
use Illuminate\Http\Request;
class TestController extends Controller
{
public function test()
{
$user = User::first();
$comments = $user -> comments;
foreach ($comments as $comment)
{
return $comment -> commentable;
}
}
}
And it still throws query exception Unknown column posts.id
Please explain. Thanks.

You can set the custom id field name in the relationship.
public function comments()
{
return $this->morphMany('App\Comment', 'commentable', 'commentable_type', 'commentable_id', 'custom_id');
}
There are the parameters
public function morphMany($related, $name, $type = null, $id = null, $localKey = null);
Edit : After going through the whole thing i've found out that using custom id only works from parent fetches the child relationship. But fails when trying to get the parent using the children. So fetching Post or Video from the comment would fail.
There's an active proposal on laravel internals to add the feature to allow specifying the custom id to make this work. https://github.com/laravel/internals/issues/587

Related

How to get the "catagory name" in Laravel?

How to get "category name" show in the product table not as "category_id"?
I already try to combine any solutions for this. But still can't solve this prob.
I'd love to hear other suggestions from the masters here.
Category Model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Kategori extends Model
{
use HasFactory;
protected $casts = [
'updated_at' => 'datetime:d/m/Y, H:i:s'
];
public function Kategori()
{
return $this->hasMany('App\Models\Produk');
}
}
Product Model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Produk extends Model
{
use HasFactory;
protected $casts = [
'updated_at' => 'datetime:d/m/Y, H:i:s'
];
public function Produk()
{
return $this->belongsTo('App\Models\Kategori', 'kategori_id');
}
}
Category Table
Product Table
Product Controller >>>> in my opinion may be my prob at here, but not so sure.
<?php
namespace App\Http\Controllers;
use App\Models\Produk;
use RealRashid\SweetAlert\Facades\Alert;
use Yajra\Datatables\DataTables;
use Illuminate\Http\Request;
class ProdukController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
public function json(){
return Datatables::of(Produk::all())->make(true);
}
public function index(){
return view('back.produk.show');
}
}
Pass the other model using your relationship
public function json(){
return Datatables::of(Produk::with('produk')->get())->make(true);
}
to which say that is named $produks, you can access it as
$produk->produk->nama;
As a side note, Do name your relationships the names of the other model.
for example, in the Kategori class, the relationship to Produk should be named produks (it is a hasMany relationship) as opposed to Kategori. Similarly, in the Produk class, the relationship to Kategori being named kategori() to which from the above answer you access it like
$produk->kategori->nama;
You should use:
public function json(){
return Datatables::of(Produk::with('Kategori')->all())->make(true);
}
I recommend to use camelCase for method names. I'm not sure how Datatables will handle this case.
In your ProdukController you need pass below code.
$result = Produk::with('Produk')->get();
When you dd($result);, you should see the related models in the relations array attribute.
To access the relations' properties from there, it is simply
$result->Produk->catagory_name

Cannot establish relationship between two tables in Laravel

I want to create a relation between lising and attribute table in laravel for that i have used following code to establish relationship between them but the data in my view is not coming from both the tables. I'm getting following error:
Call to undefined relationship [adListAttributes] on model
[App\Models\AdListing].
Here listing can have as many attribute associated with and attributes
can be associated to many listings
ad_listings:
id
title
name
date
ad_list_attributes table :
id
listing_id
name
namespace App\Models;
use Eloquent;
use Illuminate\Database\Eloquent\Model;
class AdListAttribute extends Model
{
protected $table = "ad_list_attributes";
public function Listings()
{
return $this->belongsToMany('AdListing', 'id', 'listing_id');
}
}
namespace App\Models;
use Eloquent;
use Illuminate\Database\Eloquent\Model;
class AdListing extends Model
{
protected $table = "ad_listings";
public function Attributes()
{
return $this->belongsToMany('AdListAttribute', 'listing_id', 'id');
}
}
Problem is that you are using belongsToMany in both the models.This will cause a problem.
In AdListAttribute model,
public function listing_information()
{
return $this->belongsTo('App\AdListing', 'id', 'listing_id');
}
In AdListing model,
public function adlisting_attributes()
{
return $this->hasMany('App\AdListAttribute', 'listing_id', 'id');
}
You can get the results using,
$response = AdListing::get();
if($response->adlisting_attributes)
{
foreach($response->adlisting_attributes as $attribute)
{
echo $attribute->name;
}
}
Problem is that ur not calling the relationship with the right name i assume
$listings = AdListing::with('Attributes')->get();
Update :
Try this :
use App\Models\AdListAttribute;
//
return $this->belongsToMany(AdListAttribute::class, 'listing_id', 'id');
Same for other model, then try

Argument 1 passed to App\Http\Controllers\ApiController::showAll() must be an instance of Illuminate\Database\Eloquent\Collection

I want to to retrieve all buyers for a specific saller.When I remove pluck and others methods chaining after get method it's working. But is not exact thing that I want. How Can I solve this provlem?
(source: licdn.com)
<?php
namespace App\Http\Controllers\Seller;
use App\Http\Controllers\ApiController;
use App\Seller;
use Illuminate\Http\Request;
class SellerBuyerController extends ApiController
{
public function index(Seller $seller)
{
$buyers = $seller->products()
->whereHas('transactions')
->with('transactions.buyer')
->get()->pluck('transactions')
->collapse()->pluck('buyer')
->unique('id')
->values();
return $this->showAll($buyers);
}
protected function showAll(Collection $collection, $code = 200)
{
return $this->successResponse($collection, $code);
}
protected function successResponse($data, $code)
{
return response()->json($data, $code);
}
}
Seller model hasMany relation to products
<?php
namespace App;
use App\Scopes\SellerScope;
class Seller extends User
{
public function products()
{
return $this->hasMany(Product::class);
}
}
Product Model hasMany relation to transactions
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Product extends Model
{
use SoftDeletes;
protected $fillable = [
'name', 'description', 'quantity', 'status', 'image', 'seller_id',
];
public function transactions()
{
return $this->hasMany(Transaction::class);
}
}
Transaction Model and relation to buyer
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Transaction extends Model
{
use SoftDeletes;
protected $fillable = [
'quantity', 'buyer_id', 'product_id'
];
public function buyer()
{
return $this->belongsTo(Buyer::class);
}
}
You are missing an import at the top:
use Illuminate\Support\Collection;
otherwise it assumes Illuminate\Database\Eloquent\Collection is to be used.
And values() obviously returns the support collection, not an eloquent one.
If you have a relationship from Buyer to Transaction you can go at this from the other direction to get buyers. You also need to make sure there is a relationship from Product to Seller (make sure you have the inverse of every relationship setup)
Buyer::whereHas('transactions.products.seller', function ($query) use ($seller) {
$query->where('id', $seller->id); // might have to be a more specific key name
})->get();
You would end up with a Eloquent Collection of Buyers who have transactions including products from a particular seller.
you should put use Illuminate\Support\Collection; in folder traits over apiResponser.php

insert data to table pivot use form and show it index.blade.php in laravel 5.7

I have form create team.blade.php below this
Form Team index.blade.php
display the name of the one-team user with that user, and display the project that is being done by the user, and display the user as what (role).
the relationship of one user has many teams. and one team has many users. therefore, I choose many to many relations. but when I create team, I want to insert user_id and team_id in the pivot user_teams table as the relation table between user and team.
but when I tried to create team failed, he did not save data to the user_teams table.
and in the team index, he does not display the name of a team user with that user, and displays the project that is being done by the user, and displays the user as what.
my user models
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use App\Presence;
use App\Models\Project;
use App\Productivity;
use App\Sick_leave;
use App\Annual_leave;
use App\Models\Team;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password', 'role_id',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function role()
{
return $this->belongsTo(Role::class, 'role_id');
}
public function teams()
{
return $this->belongsToMany(Team::class, 'user_teams');
}
public function projects()
{
return $this->belongsToMany(Project::Class, 'user_projects');
}
}
Team Models
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use App\User;
use App\Role;
use Auth;
class Team extends Model
{
use SoftDeletes;
protected $table = 'teams';
protected $fillable = [
'id',
'project_id',
];
public function users()
{
return $this->belongsToMany(User::class, 'user_teams');
}
public function project()
{
return $this->belongsTo(Project::class);
}
public function role()
{
return $this->belongsTo(Role::class);
}
}
Project Model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Project extends Model
{
use SoftDeletes;
protected $table = 'projects';
protected $fillable = [
'project_id',
'project_name',
'start_date',
'end_date',
'project_category',
];
public function users()
{
return $this->belongsToMany(User::class, 'user_projects');
}
public function team()
{
return $this->hasOne(Team::class);
}
}
UserTeam model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class UserTeam extends Model
{
use SoftDeletes;
protected $table = "user_teams";
public function team()
{
return $this->belongsTo(Team::class);
}
public function user()
{
return $this->belongsTo(User::class);
}
}
Team Controller
public function index()
{
$users = auth()->user()->name;
$users = User::all();
return view ('teams.index', compact ('teams', 'users', 'projects'));
}
public function create()
{
$users = User::all();
$projects = Project::pluck('project_name', 'id');
return view ('teams.form', compact('projects', 'users'));
}
public function store(Request $request)
{
$team = Team::create($request->all());
$userIds = User::find(2);
$team->users()->attach($userIds);
return redirect()->route('team.create');
}
In user_teams has fields user_id and team_id. how do i overcome this??
You have to create the team and then attach the users that belong to it.
Example from the docs:
Attaching
Eloquent also provides a few additional helper methods to make working
with related models more convenient. For example, let's imagine a user
can have many roles and a role can have many users. To attach a role
to a user by inserting a record in the intermediate table that joins
the models, use the attach method:
$user = App\User::find(1);
$user->roles()->attach($roleId);
In your case:
Team Controller
public function store(Request $request)
{
$team = Team::create($request->except('user_id'));
$team->users()->attach($request->get('user_id', []));
return redirect()->route('team.create');
}

ORM not working in Default UserController & User Model in laravel

I want to get User wise Role. here is I'm facing error ....
UserController.php ( user controller file )
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests\UserRequest;
use App\Employee;
use App\Role;
use App\User;
use App\Site;
use App\Client;
use App\ProjectType;
use App\UserPermission;
use Auth;
use DB;
use App\Project;
class UsersController extends BaseController {
public function __construct() {
$this->isSetClientAndProjectType();
$data = User::with('Role')->first();
echo "<pre>";print_r(json_decode($data)); die;
}
}
User.php ( user model file )
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Database\Eloquent\SoftDeletes;
class User extends Authenticatable {
use SoftDeletes;
use Notifiable;
protected $fillable = [
'name', 'role_id', 'password', 'siteid', 'email', 'status', 'allowed_to_bypass_pm', 'allowed_to_bypass_admin'
];
protected $hidden = [
'password', 'remember_token',
];
// Get users roles
public function Role() {
return $this->hasMany('App\Role', 'role_id', 'id');
}
}
Error is
How can i solve this error?
Help me guys.
Thank You.
If a user has many "roles" it should be public function roles().
You have defined:
A single user has a role_id
Therefore you need:
If a user has a single role it would be:
public function role() {
return $this->belongsTo('App\Role');
}
The reverse on the Role model would be:
public function users() {
return $this->belongsToMany('App\User');
}
Since many users can have the same role.
Hope this helps.
You need to add belongsTo relationship
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Database\Eloquent\SoftDeletes;
class User extends Authenticatable {
use SoftDeletes, Notifiable;
protected $fillable = [
'name', 'role_id', 'password', 'siteid', 'email', 'status', 'allowed_to_bypass_pm', 'allowed_to_bypass_admin'
];
protected $hidden = [
'password', 'remember_token',
];
// Get user's role
public function role() {
return $this->belongsTo('App\Role');
}
}
Now fetch data
$user = User::with('role')->find(1);
$role = $user->role;
You need to make sure your table structure and foreign key references are compatible with the model relationship methods used.
For example, you have used "HasMany" relationship on User model. For that, you will have to make sure that each record/row in users table(User model) "has many" associated records/rows in roles table(Role model).
Here HasMany method assumes a foreign key "role_id" on roles table(Role Model). On not finding of which, it throws error.
You first need to take in consideration the table structure of roles and users table(User and Role model) as per your requirement, and than add model relationship methods accordingly.
It can be a bit tricky if you are using the methods for the first time, you can refer the laravel documentation for the same:
eloquent-relationships

Resources