belongsTo relationship in laravel 5.8 - php

I want to make a relation between post and user to be able to get all posts by this way $user->posts() and to get user by this way $post->user()
I made belongsTo function but i need a way so when i get the user i can find all his posts somehow
also when i get the post i used \App\Post::find(1)->user()->name it return nothing
Post Model
class Post extends Model
{
public function user() {
return $this->belongsTo('App\User',null,'userid');
}
}
Post DB Structure
Schema::create('posts', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('title');
$table->longText('body');
$table->string('thumbnail');
$table->integer('views');
$table->integer('likes');
$table->bigInteger('userid');
$table->integer('categoryid');
$table->timestamps();
});
User Model has nothing in it rather than laravel defaults because user has no columns that refer to posts
User DB Structure is Laravel Default
Foreach code:
#foreach(\App\Post::find(4)->user() as $user)
<p>{{$user->name}}</p>
#endforeach
i expected it to get the user name but it didn't..

Use the hasMany relationship.
Within user model:
public function posts()
{
return $this->hasMany(Post::class, 'userid', 'id');
}
Now, you are able to get all user posts:
$posts = User::find($someId)->posts()->get();
//or
$posts = User::find($someId)->posts;
Docs about has many relationship
Hope it helps.

In User model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use App\User;
class Post extends Model
{
/**
* Get the comments for the blog post.
*/
public function user()
{
return $this->belongsTo('App\User');
}
}
In User model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use App\Post;
class User extends Model
{
/**
* Get the posts for the user.
*/
public function comments()
{
return $this->hasMany('App\Post');
}
}
Now you can access posts of user as App\User::find(id)->posts

Related

Call to undefined method App\Models\Comment::comments()

I wanted to add comment to every post I make but I keep on getting errors.
Comment Controller:
public function store(Request $request)
{
$comments = new Comment;
$comments->body =$request->get('comment_body');
$comments->user()->associate($request->user());
$blogs = Comment::find(1);
$blogs->comments()->save($comments);
return back();
}
Comment Model:
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
use HasFactory;
protected $guarded =[];
public function blog()
{
return $this->belongsTo(Blog::class);
}
public function user()
{
return $this->belongsTo(User::class);
}
}
Blog Model:
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Blog extends Model
{
use HasFactory;
protected $fillable = ['user_id' , 'blog_category_id' , 'title' , 'description'];
public function user()
{
return $this->belongsTo(user::class);
}
public function blogcategory()
{
return $this->hasOne(BlogCategory::class)->withDefault(function($user , $post){
$user->name = "Author";
});
}
public function comments()
{
return $this->hasMany(Comment::class);
}
}
You are using the wrong model; the Blog model has the comments relationship not the Comment model:
$blog = Blog::find(...);
$blog->comments()->save(...);
Update:
You seem to want to be using a Polymorphic relationship it would seem based on the structure of your comments table since you have the fields commentable_id and commentable_type. If you check the documentation for the Polymorphic One to Many relationship this is the same as the example in the documentation:
Blog model:
public function comments()
{
return $this->morphMany(Comment::class, 'commentable');
}
Comment model:
public function commentable()
{
return $this->morphTo();
}
Laravel 8.x Docs - Eloquent - Relationships - Polymorphic Relationships - One to Many
Having said that, your Comment model doesn't look like you wanted to use a polymorphic relationship since you specifically had a blog relationship method. If you do not have more than 1 entity that needs to be related to Comment I would not be using a polymorphic relationship.

morphToMany real many to many relation

All polymorh examples I found are one to many if I get it correct. (Tag to Post / Video e.g)
In my Case the parent class is multiple and the child class also. Therefore i set up the pivot table
Tables
Person
id
Venture
id
Capital
id
Estate
id
PIVOT TABLE
Revenues
emitter_id //ID of the revenue emitting class (Venture, Capital, Estate)
emitter_type // Class of the Emitter (App\Models\Venture App\Models\Estate)
receiver_id // Id of Receiver (Venture or Person)
receiver_type // type of Receiver (App\Models\Venture or App\Models\Person)
revenue
In the Estate Model i try this
public function revenuePersons()
{
// searched type, own type/id ,tabel own ID to search id
return $this->morphToMany(Person::class, 'emitter' ,'revenues' ,'emitter_id','receiver_id')
->withPivot('revenue');
}
One the Person Model
public function estaterevenues(){
// searched type, own type/id ,tabel own ID to search id
return $this->morphToMany(Estate::class, 'receiver' ,'revenues' ,'receiver_id','emitter_id')
->withPivot('revenue');
}
The Code works but in some cases i get additional relations back. So it seams the searched _type is not correctly considered.
So i started to implement a own database query function that gives me the Revenue Entry back. It works correctly.
Revenue Model
public function getRevenue($ownside, $emitter_id = Null, $emitter_type,$receiver_id=Null, $receiver_type ){
$revenue = DB::table('revenues')
->where('emitter_id', $emitter_id)
.....()->get()}
But I am not able to do something like
$persons->getRevenues
because a Relationship is expected as return value
So if anyone has an idea how to do that correctly I would be very happy. Or some other best practices for this many to many approach.
The second Question is how to get all revenue receiver at once.
Instead of
$estate->revenuepersons
$estate->revenueventures
Have something like
$estate->revenues //that list both, Ventures and Persons
And here a Class Diagram
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
/**
* Get all of the tags for the post.
*/
public function tags()
{
return $this->morphToMany(Tag::class, 'taggable');
}
}
namespace App;
use Illuminate\Database\Eloquent\Model;
class Video extends Model
{
/**
* Get all of the tags for the post.
*/
public function tags()
{
return $this->morphToMany(Tag::class, 'taggable');
}
}
namespace App;
use Illuminate\Database\Eloquent\Model;
class Tag extends Model
{
/**
* Get all of the posts that are assigned this tag.
*/
public function posts()
{
return $this->morphedByMany(Post::class, 'taggable');
}
/**
* Get all of the videos that are assigned this tag.
*/
public function videos()
{
return $this->morphedByMany(Video::class, 'taggable');
}
}
$post = Post::find(1);
dd($post->tags);
$video = Video::find(1);
dd($video->tags);
$tag = Tag::find(1);
dd($tag->posts);
$tag = Tag::find(1);
dd($tag->videos);
posts table migration:
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->string("name");
$table->timestamps();
});
videos table migration:
Schema::create('videos', function (Blueprint $table) {
$table->increments('id');
$table->string("name");
$table->timestamps();
});
tags table migration:
Schema::create('tags', function (Blueprint $table) {
$table->increments('id');
$table->string("name");
$table->timestamps();
});
taggables table migration:
Schema::create('taggables', function (Blueprint $table) {
$table->integer("tag_id");
$table->integer("taggable_id");
$table->string("taggable_type");
});

create the anchor tag by using the morph relation in Laravel blade view

I have an application where an Invoice can belong to the client or supplier. Now I used the morph things in my current scenario. I want to create the proper anchor by using the morph relation But I didn't find the best way with Laravel
Client.php
class Client extends Model
{
/**
* Get the client's invoices.
*/
public function invoices()
{
return $this->morphMany('App\Invoice', 'contact');
}
}
Supplier.php
class Supplier extends Model
{
/**
* Get the supplier's invoices.
*/
public function invoices()
{
return $this->morphMany('App\Invoice', 'contact');
}
}
Invoice.php
class Invoice extends Model
{
/**
* Get the owning contact model.
*/
public function contact()
{
return $this->morphTo();
}
}
Now at somewhere(invoice details page), where I want to add the anchor to the contact of the invoice(either supplier or client) But I need to know if there is any Laravel's way.
If the contact of the invoice belongs to App\Client then the href will be "/clients/contact_id" or if it belongs to App\Supplier then it should be "/supplier/contact_id"
invoices/show.blade.php
<b>{{ $invoice->contact->name }}</b>
You can try given solution for you problem.
<?php
//You can see here for all table migration files
// For Client Table
Schema::create('client', function (Blueprint $table) {
$table->increments('id');
$table->string("client_name");
$table->timestamps();
// You can add your more fields and you can change field name also
});
// For Supplier Table
Schema::create('supplier', function (Blueprint $table) {
$table->increments('id');
$table->string("supplier_name");
$table->timestamps();
// You can add your more fields and you can change field name also
});
// For Invoice Table
Schema::create('invoices', function (Blueprint $table) {
$table->increments('id');
$table->morphs('invoice');
$table->timestamps();
// You can add your more fields and you can change field name also
});
//Note:
$table→morphs('invoice') would automatically create two columns using the text passed to it + “able”. So it will result in invoiceable_id and invoiceable_type.
?>
Here are your model for morphTo replationship
Client Model: Client.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Client extends Model
{
/**
* Get all of the Client's invoices.
*/
public function invoices()
{
return $this->morphMany(Invoices::class, 'invoiceable');
}
}
?>
Supplier Model: Supplier.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Supplier extends Model
{
/**
* Get all of the Supplier's invoices.
*/
public function invoices()
{
return $this->morphMany(Invoices::class, 'invoiceable');
}
}
?>
Invoices Model: Invoices.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Invoices extends Model
{
/**
* Get all of the owning invoiceable models.
*/
public function invoiceable()
{
return $this->morphTo();
}
}
?>
Now you can retrieve records using Client and Supplier using polymorphic relationship.
Retrieve records using client models.
$client = Client::find(1);
dd($client->invoices);
Retrieve records using Supplier models.
$supplier = Supplier::find(1);
dd($supplier->invoices);
You can also retrieve records
$client = Client::find(1);
foreach ($client->invoices as $invoice) {
<a href="{{ route('view-client', ['id' => $invoice->id]) }}">
<b>{{ $invoice->client_name }}</b>
</a>
}

Problem with Laravel Eloquent - relation not working

I'am beginner in Laravel. I have project in Laravel 5.8.
I have User model:
class User extends Authenticatable implements MustVerifyEmail
{
use Notifiable;
use psCMS\Presenters\UserPresenter;
use scopeActiveTrait;
public static $roles = [];
public $dates = ['last_activity'];
// ...
public function scopeHistory()
{
return $this->hasMany('App\UserLoginHistory');
}
// ...
}
and UserLoginHistory:
class UserLoginHistory extends Model
{
protected $quarded = ['id'];
public $timestamps = false;
protected $fillable = ['user_id', 'date_time', 'ip'];
public function user()
{
return $this->belongsTo('App\User');
}
}
I want show user login history by this code:
User::history()->where('id', $idAdmin)->orderBy('id', 'desc')->paginate(25);
but it's not working.
This function not working - I haven't got results.
How can I fixed it?
First of all, you are defining your relationship as a scope (prefixing the relationship with the scope keyword). Try updating your model relationship to this:
public function history()
{
return $this->hasMany('App\UserLoginHistory');
}
Then, given your query, it seems that you want to get all the UserLoginHistory
records for a given User. You could accomplish this in two ways (at least).
From the UserLoginHistory model itself, constraining the query by the foreign key value:
$userId = auth()->id(); // get the user ID here.
$results = UserLoginHistory::where('user_id', $userId)->paginate(15);
// ^^^^^^^ your FK column name
From the User model using your defined relationship:
$userId = auth()->id(); // get the user ID here.
$results = User::find($userId)->history;
The downside of the second approach is that you'll need to paginate the results manually.
in your User model you should define your relation by this way :
public function history()
{
return $this->hasMany('App\UserLoginHistory');
}
then if you would like to select with history model you can do that with WhereHas() method :
User::whereHas(['history'=>function($q) use ($idAdmin) {
$q->where('id',$idAdmin)
}])->orderBy('id', 'desc')->paginate(25);
You must be do this changes
public function history()
{
return $this->hasMany('App\UserLoginHistory');
}
usage
$user = User::find($idAdmin);
$userHistories = $user->history()->latest()->paginate(25);
or get user with all history
User::with('history')->find($idAdmin);
// Post model
namespace App;
use App\User;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
public function categories()
{
return $this->belongsToMany('App\Category')->withTimestamps();
}
}
// Category model
namespace App;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
public function posts()
{
return $this->belongsToMany('App\Post')->withTimestamps();
}
}

Specific role relations

I work on one project with Laravel 5.2 and Entrust package for ACL.
In this project I need for one Role ('venue_owner') in which venue is owner. I have also table called venue and I have no idea how to make this relations, because table users is general for all type of users.
How to make this relations to know what user from role venue_owner is owner of what venues ?
Have you created your Migrations yet by running: php artisan enthrust:migration? if not it, run it and then inside the file that is generated, add your own tables like below within the up() Method of the Enthrust Migration File:
<?php
public function up() {
// SOME OTHER TABLE CREATION CODES...
Schema::create('venue_owner', function (Blueprint $table) {
$table->increments('id');
$table->integer("user_id")->unsigned();
$table->timestamps();
// CREATE THE ASSOCIATION/RELATIONSHIP USING FOREIGN KEY
$table->foreign('id')
->references('id')
->on('venue')
->onDelete('cascade');
});
Schema::create('venues', function (Blueprint $table) {
$table->increments('id');
$table->integer("venue_owner_id")->unsigned();
$table->string("venue");
$table->timestamps();
// CREATE THE ASSOCIATION/RELATIONSHIP USING FOREIGN KEY
$table->foreign('venue_owner_id')
->references('id')
->on('venue_owner');
});
}
public function down() {
// OTHER DROP COMMAND CODES...
Schema::drop('venue_owner');
Schema::drop('venues');
}
Then in your Eloquent Model Class you can explicitly set the $this->hasMany() like so:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class VenueOwner extends Model {
/**
* GET ALL THE venues FOR THE venue_owner .
*/
public function venues() {
return $this->hasMany('App\Venues');
}
/**
* GET ALL THE user FOR THE venue_owner .
*/
public function user() {
return $this->hasOne('App\User');
}
And in your Venues Eloquent Model Class, you do something like:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Venues extends Model {
/**
* GET THE venue_owner FOR venue(s).
*/
public function venueOwner() {
return $this->belongsTo('App\VenueOwner');
}
Last but not least in your Users Eloquent Model Class, you do something like:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Users extends Model {
/**
* GET THE user Information FOR venue_owner.
*/
public function venueOwner() {
return $this-> hasOne('App\VenueOwner');
}
Now, you can get all information about the venue_owner and his venues and roles & permissions using the user_id.

Categories