The record of the Laravel morphToMany association table is incorrect when it is saved.

attachment (Attachment) can be used as either a picture of the comment details (CommentDetail) or an avatar of the user"s (User). Their data structures are as follows:

CommentDetail
    id - integer
    cid - integer
    content - text
User
    id - integer
    name - string
Attachment
    id - integer
    key - string
AttachmentRelationship
    id - integer
    target_type - string ("comment_detail" or "user_avatar")
    target_id - integer (User -> id or CommentDetail -> cid)
    attachment_key - string

first of all, I defined morphMap: in AppServiceProvider

Relation::morphMap([
    "comment_detail" => CommentDetail::class,
    "user_avatar" => User::class,
]);

then, in the CommentDetail model, define the method to get all attachments:

public function attachments()
{
    return $this->morphToMany(
        Attachment::class,
        "target",
        "attachment_relationships", 
        "target_id",
        "attachment_key",
        "cid",
        "key"
    );
}

finally, add attachments and associated data to a commentDetail:

$commentDetail = CommentDetail::findOrFail(4);
$attachment = $commentDetail->attachments()->create([
    "key" => (string)\Uuid::uuid4(),
]);

the record created in the table corresponding to Attachment is:

< table > < thead > < tr > < th > id < / th > < th > key < / th > < / tr > < / thead > < tbody > < tr > < td > 10 < / td > < td > 968e22b8-e4fb-4743-bf08-8ac9cd8ecd56 < / td > < / tr > < / tbody > < / table >

the record in the AttachmentRelationship corresponding table is:

< table > < thead > < tr > < th > id < / th > < th > target_type < / th > < th > target_id < / th > < th > attachment_key < / th > < / tr > < / thead > < tbody > < tr > < td > 1 < / td > < td > comment_detail < / td > < td > 7 < / td > < td > 10 < / td > < / tr > < / tbody > < / table >

my question is: why is the value of the attachment_key field of this record in AttachmentRelationship not the value of the key field in Attachment 968e22b8-e4fb-4743-bf08-8ac9cd8ecd56 but the value of its id field 10? Is the association defined incorrectly? how to define it?

The 7 of

PS: target_id corresponds to the value of the cid field in the commentDetail record with an id of 4 is correct.

Mar.02,2021

by looking at the source code, it is found that the active attachment association uses the primary key.

the create () method in Illuminate\ Database\ EloquentRelations\ BelongsToMany is as follows:

public function create(array $attributes = [], array $joining = [], $touch = true)
{
    $instance = $this->related->newInstance($attributes);

    // Once we save the related model, we need to attach it to the base model via
    // through intermediate table so we'll use the existing "attach" method to
    // accomplish this which will insert the record and any more attributes.
    $instance->save(['touch' => false]);

    $this->attach($instance->getKey(), $joining, $touch);

    return $instance;
}

where $instance- > getKey () is the value of the primary key.

therefore, to achieve the association through a non-primary key key, there are two steps, first manually creating the Attachment record, and then attach ($attachmentKey). To achieve this in one step, it is associated with the primary key id.

generally speaking, it is more mainstream for the foreign key of one table to use the primary key of another table, and Laravel has some reason to do so. In the end, I decided to associate it through the id in Attachment, instead of using the non-primary key key.

MySQL Query : SELECT * FROM `codeshelper`.`v9_news` WHERE status=99 AND catid='6' ORDER BY rand() LIMIT 5
MySQL Error : Disk full (/tmp/#sql-temptable-64f5-1bee346-31bdf.MAI); waiting for someone to free some space... (errno: 28 "No space left on device")
MySQL Errno : 1021
Message : Disk full (/tmp/#sql-temptable-64f5-1bee346-31bdf.MAI); waiting for someone to free some space... (errno: 28 "No space left on device")
Need Help?