eloquent belongsTo确定关系表

时间:2016-07-18 09:27:02

标签: php laravel eloquent

我有3个表,news表商店新闻,songs表商店歌曲,comments表商店评论,新闻可以有很多评论,一首歌也可以有很多评论,在我的comments表中,我使用item_iditem_type来确定此评论所属的父模型。例如,item_type='game' and item_id=1比此评论属于game表,游戏ID = 1。 以下是我的型号代码。

class Song
{
    public function comment()
    {
        return $this->hasMany(Comment::class, 'item_id', 'id')->where('comments.item_type', '=', Comment::SONG_COMMENT_TYPE);
    }
}

消息

class News
{
    public function comment()
    {
        return $this->hasMany(Comment::class, 'item_id', 'id')->where('comments.item_type', '=', Comment::NEWS_COMMENT_TYPE);
    }
}

评论

class Comment
{
    public function song()
    {
        return $this->belongsTo(Song::class, 'item_id', 'id');
    }
    public function news()
    {
        return $this->belongsTo(News::class, 'item_id', 'id');
    }
}

SongNews模型获取评论很容易,但我不知道如何定义反向关系,是否可以在{中定义方法{1}}模型如:

Comment

或者我可能以错误的方式思考,如何使用eloquent来确定在运行时加入哪个表?

2 个答案:

答案 0 :(得分:1)

要实现多态关系,我认为您的数据库应如下所示:

news
    id
    ...

songs
    id
    ...

comments
    id
    commentable_id
    commentable_type

然后,每个模型的关系应如下所示:

class Comment extends Model
{
    /**
     * Get all of the owning commentable models.
     */
    public function commentable()
    {
        return $this->morphTo();
    }
}

class News extends Model
{
    /**
     * Get all of the news' comments.
     */
    public function comments()
    {
        return $this->morphMany('App\Comment', 'commentable');
    }
}

class Song extends Model
{
    /**
     * Get all of the song's comments.
     */
    public function comments()
    {
        return $this->morphMany('App\Comment', 'commentable');
    }
}

在此处进一步阅读:https://laravel.com/docs/5.2/eloquent-relationships#polymorphic-relations

答案 1 :(得分:1)

一个简单的解决方案可能是使用新闻模型作为起点,并将评论表加入两个简单的表格。

示例可能如下所示:

// Comment

public function news()
{

    return News::

        select('news.*') // Only select news columns (can be removed)

        ->join('comments', 'news.id', '=', 'item_id') // Join comments table

        ->where('item_type', 'news') // Make sure item type is news

        ->where('comments.id', $this->id) // Get $this as comment

        ->first(); // Return a single result. Maybe this is unnecessary, you
                   // should test it by removing this. I assume when this 
                   // will be removed it will return an array of results, 
                   // and that is not what you want. Right?

}

此函数将返回单个结果或NULL。

通过更改几个名字,可以为歌曲做同样的事情。

希望这会有所帮助:)