Laravel 4与命名空间模型的多态关系

时间:2014-03-20 07:33:47

标签: php laravel laravel-4 eloquent

我用Eloquent的多态关系创建了一个Seo表。所以对于Seo表,我有类似的东西

title
description
seoble_id
seoble_type
timestamps

然后对于所有具有自定义SEO的模型,我添加了morphOne关系,而Seo模型将具有morphMany关系。所以对于Post模型我会有这样的东西

namespace App\Models;

class Post extends Eloquent {
  public function seo()
  {
    return $this->morphOne('App\Models\Seo', 'seoble');
  }
}

但是,只有当seoble_type填充完全命名空间的模型类名时,该关系才有效。所以seoble_type必须是'App \ Models \ Post'(模型名称如'Post'或表名如'posts'不起作用)才能使多态关系起作用。问题是,如果我想以某种方式更改名称空间,我将不得不更新所有seo表以更新seoble_type字段,这将是一个麻烦。

现在,在我尝试多态关系之前,我通常创建了这样的等效表:

title
description
object_id
type
timestamps

对于这种关系,对于每个模型我会有这样的事情:

namespace App\Models;

class Post extends Eloquent {
  public function seo()
  {
    return $this->hasOne('App\Models\Seo', 'object_id')->where('type', 'post');
  }
}

我的问题是,这两种方法是否相同?

1 个答案:

答案 0 :(得分:1)

如果使用变形,则表示您希望单个表可以用作任何具有object_id和type_id指示的表的关系。所以你的问题的答案并不等同。

我认为在你的情况下(保存seo表)推荐的方式,因为我的意见是使用morphOne。

然后,对于你在变形中的问题,你可以用你喜欢的任何东西填充你的seoable_type,而不是填充你的命名空间

这里是使用morph的简单代码:

namespace App\Models;

class Seo extends Eloquent {

    public function seoable()
        {
           return $this->morphTo();
        }

    public function post()
    {
        return $this->belongsTo('App\Models\Seo', 'seoable_id');
    }
}

/*----*/

namespace App\Models;

class Post extends Eloquent {

    public function getSeo($type)
    {
        return $this->morphOne('App\Models\Seo', 'seoable');
    }
}


// you can using like this :
$seo = \Seo::where('seoable_type', 'post');
$seo->post->first();

// or like this : 
$post = \Post::with('getSeo')->findOrFail($id)->toArray();

希望这对你有所帮助。