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

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.

Related

How can i select specific field name using belongTo relationship in laravel model using eloquent?

I want to fetch only one columns which has name image_url from relationship table. relationship on table is belongsTO.
i am confused how to fetch only single column value with belongsTo relation.
below is my model.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class PropertyImageGallery extends Model
{
use HasFactory;
protected $fillable = ['property_id', 'name', 'size','image_url'];
public function property()
{
return $this->belongsTo(Property::class);
}
}
please help me.
You can try this:
public function property()
{
return $this->belongsTo(Property::class)->select(['property_id', '...']);
}
BelongsTo relationship like below:
public function parent()
{
return $this->belongsTo(Parent::class,'foreign_key','owner_key');
}
it would be:
public function property(){
return $this->belongsTo(Property::class,'property_id','id');
}
you should call it like this in your controller :
$yourParentElement = ParentModel::find(1);
return $yourParentElement ->Property->image_url ;
check this for more infos: Eloquent: Relationships (Belongs To)

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();
}
}

Many To Many (Polymorphic) using the same model with different types

I have these 3 tables in the database:
I'm using Many To Many (Polymorphic) Eloquent relationship to connect the Models. The problem is that the Creadores table can be of type artista or autor in the Creaciones table.
Is it possible to tell Eloquent when to use artista or autor?
It works if I extend the Creador Model into 2 other Models: Artista and Autor. But when I want to show all the creaciones of a creador using the Creador Model, it's not possible because the Polymorphic relationship was created with the extended models.
Libro Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use ChrisKonnertz\BBCode\BBCode;
class Libro extends Model
{
protected $table = 'Libros';
// Return all the artists of the book
public function artistas()
{
return $this->morphedByMany('App\Creador', 'creador', 'creaciones');
}
// Return all the authors of the book
public function autores()
{
return $this->morphedByMany('App\Creador', 'creador', 'creaciones');
}
}
Creador Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Creador extends Model
{
protected $table = 'creators';
// Return all the books where author
public function autorLibros()
{
return $this->morphToMany('App\Libro', 'creador', 'creaciones');
}
// Return all the books where artist
public function artistaLibros()
{
return $this->morphToMany('App\Libro', 'creador', 'creaciones');
}
}
You might be better off just adding a type property to Creador with 'artista'/'autor' in it.
The polymorphic relationship can only take a single model.
So your code would then become:
public function creadors()
{
// Return a general relation for all 'creadores'.
return $this->morphedByMany(App\Creador::class, 'creador', 'creaciones');
}
public function artistas()
{
// Filter for 'artista's.
return $this->creadors()->where('type', 'artista');
}
public function autores()
{
// Filter for 'autor's.
return $this->creadors()->where('type', 'autor');
}
Solved it the following way. Changed the relation from a Polymorphic Many to Many to a normal Many to Many, adding withPivot and wherePivot.
Creador Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Creador extends Model
{
protected $table = 'creators';
public function libros()
{
return $this->belongsToMany('App\Libro', 'creaciones')->withPivot('creador_type');
}
// All books as an Artist
public function librosArtista()
{
return $this->libros()->wherePivot('creador_type', 1);
}
// All books as an Author
public function librosAutor()
{
return $this->libros()->wherePivot('creador_type', 2);
}
}
Libro Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use ChrisKonnertz\BBCode\BBCode;
class Libro extends Model
{
protected $table = 'libros';
public function creador()
{
return $this->belongsToMany('App\Creador', 'creaciones')->withPivot('creador_type');
}
// All book artists
public function artistas()
{
return $this->creador()->wherePivot('creador_type', 1);
}
// All book authors
public function autores()
{
return $this->creador()->wherePivot('creador_type', 2);
}
}
And when creating a attaching a Creador to a Libro:
$libro->artistas()->attach( $creador, [
'creador_type' => 1
]);

Laravel 5.4 many to many relationships with foreign key

i'm using a data table with name auct_lots_full for my Lot.php model, where primary key is lot_id, in order everything to work i used Sofa/Eloquence extension, Mappable. So this is my model :
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Sofa\Eloquence\Eloquence;
use Sofa\Eloquence\Mappable;
class Lot extends Model
{
use Eloquence, Mappable;
protected $table = 'auct_lots_full';
protected $maps =[
'id' => 'lot_id',
];
public function scopeFilter($query, QueryFilter $filters)
{
return $filters->apply($query);
}
public function comments()
{
return $this->hasMany(Comment::class);
}
}
But he problem is that in some cases it keeps looking for id column as primary key. For example in LotsController.php i have this problem here :
public function show($id)
{
$lot = Lot::find($id);
return view('lots.show')->withLot($lot);
}
But i fix this problem with this solution:
public function show($id)
{
$lot = Lot::where('lot_id', $id)->first();
return view('lots.show')->withLot($lot);
}
But i understand that is just a solution for only this function...
So the same problem i have in CommentsController.php:
public function show()
{
$comments = Comment::orderBy('id', 'desc')->paginate(30);
return view('comments.browse', compact('comments'));
}
And i don't know how to fix it. Could any one explain me why is this happening? Is there a better way than use an extension? How i can fix this error in CommentsCotroller.php ?
This is the Comment.php model:
<?php
namespace App;
class Comment extends Model
{
public function lot()
{
return $this->belongsTo(Lot::class);
}
public function User()
{
return $this->belongsTo(User::class);
}
}
There is a primaryKey variable in your Model file which is id by default.
/**
* The primary key for the model.
*
* #var string
*/
protected $primaryKey = 'id';
If you override this variable in Lot model file. So your primary key will be lot_id instead of id as in default. Simply add this;
protected $primaryKey = 'lot_id';
So actually i find a proper way to do it with out Sofa/Eloquence extension, using not only foreign key but also a local key in many to many relationship. So this is the new code:
so for Lot.php i did this:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Lot extends Model
{
protected $table = 'auct_lots_full';
protected $primaryKey = 'lot_id';
public function scopeFilter($query, QueryFilter $filters)
{
return $filters->apply($query);
}
public function comments()
{
return $this->hasMany(Comment::class,'lot_id', 'lot_id');
}
}
Than i did same for the Comment.php model:
<?php
namespace App;
class Comment extends Model
{
public function lot()
{
return $this->belongsTo(Lot::class, 'lot_id', 'lot_id');
}
public function User()
{
return $this->belongsTo(User::class);
}
}
So what we see above, in Lot.php model, function comments i pass foreignKey: 'lot_id' in auct_lots_full table and localKey 'lot_id' in comments table witch refers to the auct_lots_full table. In Comment.php model wi did the same but in case instead of localKey it is ownerKey. Im a bad at explaining so i will attach some images to make sense.
Lot.php
Comment.php

Laravel 5.1: Get only the records of the related model

I have three models:
Category
Post
Comment
These are their implementations:
class Category extends \Eloquent {
public function posts() {
return $this->hasMany('Post');
}
}
class Post extends \Eloquent {
public function category() {
return $this->belongsTo('Category');
}
public function comments() {
return $this->hasMany('Comment');
}
}
class Comment extends \Eloquent {
public function post() {
return $this->belongsTo('Post');
}
}
Is it possible, using eloquent, to get a list (array or collection) of all the comments (and only the comments, without posts) related to a Category?
(this means, given a category find all the related posts and then return all the related comments).
Thanks in advance!
Simply use hasManyThrough relation on your model Category :
class Category extends \Eloquent {
public function posts() {
return $this->hasMany(Post::class);
}
public function comments() {
return $this->hasManyThrough(Comment:class,Post::class);
}
}
After that, you can simply call $category->comments to have a Collection with all the comments related to a Category.
See https://laravel.com/docs/5.1/eloquent-relationships#has-many-through for extra information.
For Laravel 5.3 : https://laravel.com/docs/5.3/eloquent-relationships#has-many-through

Categories