Hello everybody,
First I will explain the context, then the problem, then what I've got.
I am developing a practice app which emulates a blog. Any registered user can like a post, but also, can like other things, such as comments of a post. To do so, I created a polymorphic relationship. This feature works. This is the schema:
public function up()
{
Schema::create('likeables', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id');
$table->unsignedBigInteger('likeable_id');
$table->string('likeable_type');
$table->timestamps();
$table->unique(['user_id', 'likeable_id','likeable_type']);
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});
}
There is a model named like, which has some methods to like, unlike and those things. It all works well, I am still not describing the problem, just giving context. The model is:
protected $table = 'likeables';
protected $fillable = [
'user_id',
'likeable_id',
'likeable_type',
];
/**
* Get all of the comments that are assigned this like.
*/
public function comments()
{
return $this->morphedByMany('App\Comment', 'likeable');
}
/**
* Get all of the posts that are assigned this like.
*/
public function posts()
{
return $this->morphedByMany('App\Post', 'likeable');
}
public function path()
{
//TODO. EL path será diferente segun "likeable"
}
public function activity()
{
dump($this->id);//THIS RETURNS NULL, I can do $this->"anyOtherColumn" and it works.
return $this->morphMany(Activity::class, 'subject')->latest();//This should return subject_Type and subject_id, but it only returns the first one
}
public function recordActivity($description)
{
$this->activity()->create([
'profile_id' => auth()->user()->profile->id,
'description' => $description
]);
}
}
So, notice the method "activity()", that has a comment. I would like to obtain the ID. Why? I'll explain.
Aside from the liking functionality, I am doing a log or activity table. When the user creates a post, or a coment, or LIKES a post or coment, a entry must appear. I did it with Observers and It works flawlessly with posts or comments, but with likes, it does so so. The entry appears, but I cannot identify the ID of the row of the likeables table. I need this information because from there I can get to know if the thing liked was a comment or a post, and which one specifically.
I show you the schema for activity, but I don't think the problem is related. The problem is in the likeables table. I think laravel, in this kind of relationship, does not want to use the id.
public function up()
{
Schema::create('activities', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('profile_id');
$table->nullableMorphs('subject');
$table->string('description');
$table->text('changes')->nullable();
$table->timestamps();
$table->foreign('profile_id')->references('id')->on('profiles')->onDelete('cascade');
});
}
To sumarize, when I want the morph field 'subject', I get the subject_type and subject_id if the type is POST or COMMENT, but when it is LIKE, I do not get the subject_id. I think this happens because LIKE model is an intermidiate table.
If I dump and die and inspect the LIKE model, in the array field I see no ID, just the other columns. See example (sorry, I don't know how to format nicely in the forum):
#attributes: array:5 [
"user_id" => 4
"likeable_id" => 1
"created_at" => "2020-04-19 21:03:04"
"updated_at" => "2020-04-19 21:03:04"
"likeable_type" => "App\Comment"
]
Somehow I need laravel to use the ID column I think. To try so, I read the docs and SO and this forum for some time, and thought that the answer was to add at the likeable models (aka, comment, post) the following:
public function likes()
{
return $this->morphToMany('App\User', 'likeable')
->using('App\Like')
->withPivot('id') //This line I have added, but no result
->withTimestamps();
}
But it did not work, no behavior change with or without the line.
Thanks a lot