Laravel 4,来自一个模型的多个多态关系


Laravel 4, Multiple Polymorphic Relations from one Model

我正在尝试在 Laravel 4 中设置多态关系,以便我可以拥有一个处理与上传、取消链接等相关的所有内容的 Image 类,然后由多个不同的模型使用它。这很好,直到我尝试从同一模型创建多个链接。

例如,我目前有这样的东西:

模型/图像.php

class Image extends Eloquent {
    public function of() { return $this->morphTo(); }
}

模特/人.php

class Person extends Eloquent {
    public function mugshot() { return $this->morphOne('Image', 'of'); }
    public function photos() { return $this->morphMany('Image', 'of'); }
}

型号/地点.php

class Place extends Eloquent {
    public function photos() { return $this->morphMany('Image', 'of'); }
}

在这里,一个人可以上传一个mugshot和许多photos,而一个地方可以有很多photos。问题是,当我在 Person 上创建mugshot时,它会将其保存到数据库中的images表中:

id: 1
of_id: 1
of_type: Person

它不存储它是mugshot而不是photo的事实,所以当我去检索它时,$person->mugshot有时可能会返回$person->photos之一,反之亦然。

是否有 (a) 比在同一模型上创建 2 个链接更好的方法,或者 (b) 实际使这种方式起作用的方法?

现在没有内置方法。也许在 Laravel 4.1 中,这应该会带来多态关系的完全重写。

type属性添加到Image,然后定义关系where条件:

public function mugshot() { 
    return $this->morphOne('Image', 'of')->where('type', 'mugshot'); 
}
public function photos() { 
    return $this->morphMany('Image', 'of')->where('type', 'photo'); 
}

不要忘记在您创建的Image上设置type。或者,就像我在下面所做的那样,将该逻辑隐藏在模型中。

这是我的代码(我使用的是带有短数组表示法的 PHP 5.4):

图像:

namespace SP'Models;
class Image extends BaseModel {
    const MUGSHOT = 'mugshot';
    const PHOTO = 'photo';
    protected $hidden = ['type'];
    public function of()
    {
        return $this->morphTo();
    }
}

人:

namespace SP'Models;
use SP'Models'Image;
class Person extends BaseModel {
    public function mugshot() { 
        return $this->morphOne('SP'Models'Image', 'of')
                            ->where('type', Image::MUGSHOT); 
    }
    public function photos() { 
        return $this->morphMany('SP'Models'Image', 'of')
                            ->where('type', Image::PHOTO); 
    }
    public function saveMugshot($image)
    {
        $image->type = Image::MUGSHOT;
        $image->save();
        $this->mugshot()->save($image);
    }
    public function savePhotos($images)
    {
        if(!is_array($images))
        {
            $images = [$images];
        }
        foreach($images as $image)
        {
            $image->type = Image::PHOTO;
            $image->save();
            $this->photos()->save($image);
        }
    }
}

在控制器/服务中的某个位置:

$person->savePhotos([$image1, $image2]);