Canser Yanbakan
Canser Yanbakan

Reputation: 3870

Laravel polymorphic relation load model by morph name and foreign key

I am trying to create a comment to a commentable model (which is created by using polymorphic relations.) using the morphname key.

For example; i would like create a comment giving the morph name (blog) and foreign_key (1). But the morph name could change. So we don't know which key can be with the request. I don't want to create actions for each resource.

AppServiceProvider:

Relation::morphMap([
    'blog' => \App\Models\Blog\BlogPost::class,
    'product' => \App\Models\Commerce\Product::class,
]);

Conroller -> action:

$this->validate($request, [
    'commentable_model' => 'required|string',
    'commentable_id' => 'required|integer|min:1',
    'comment' => 'required|string'
]);

// i am trying to load data using morph name and foreign key here; but it's not working.
$model = $request->commentable_model::findOrFail($request->commentable_id);

$comment = new Comment;
$comment->comment = $request->comment;
$comment->commentable()->associate($model);
$comment->user()->associate(auth('api')->user());
$comment->save();

Commentable relation:

Schema::create('comments', function (Blueprint $table) {
    $table->increments('id');
    $table->integer('user_id')->unsigned();
    $table->text('comment');
    $table->integer('parent_id')->unsigned()->nullable();
    $table->foreign('parent_id')->references('id')->on('comments')->onDelete('cascade');
    $table->morphs('commentable');
    $table->timestamps();
});

Data:

commentable_model => 'blog', commentable_id => 1

I will send these data via api endpoints. So, i would like to use just morhpnames, not full class names.

I could not get it work.

Any ideas?

Upvotes: 1

Views: 1772

Answers (1)

Canser Yanbakan
Canser Yanbakan

Reputation: 3870

I found the solution and it was in front of my eyes all the time actually...

We are making the mapping using the Relation class.

I have checked if can we access the relations with any method or variables and the answer is yes.

The short answer is;

Relation::$morphMap

returns all the mapping as an array.

And my solution for the question is;

$model = Relation::$morphMap[$request->commentable_model]::findOrFail($request->commentable_id);

Accessing that array value using our given morph name (which is blog).

Upvotes: 3

Related Questions