【问题标题】:Laravel extended relationshipsLaravel 扩展关系
【发布时间】:2014-09-13 22:01:22
【问题描述】:

我正在开发一个具有多种语言版本的 laravel 项目。 (或者至少应该有)

我有(例如)一个 Page 模型和一个 PageTranslation 模型。 PageTranslation 模型的每个实例都是一种语言突变。

页面模型中定义了两种关系。 currentTranslationfirstTranslation。如果页面没有当前语言的翻译(currentTranslation 获取部分网址),则使用 firstTranslation

解决问题。鉴于我必须写一个类似的条件:

if($page->currentTranslation) {
    $pageTranslation = $page->currentTranslation;    
} else {
    $pageTranslation = $page->firstTranslation;
}

然后使用它。写这个真的很烦。我想要一个名为 translation 的关系,它将决定是使用 currentTranslation 还是 firstTransation 关系。 我会在该关系中做一个简单的查询,但此时 page_id 不可用。

你能告诉我一个解决方案吗?

我的第二个问题是:如果上述问题是可以解决的,是否有可能以某种方式将数据从$page->translation 传递到$page,所以我不必写$page->translation->title 而只是@ 987654325@(它会返回当前使用语言的页面标题)。

页面模型

class Page extends Eloquent {

public function firstTranslation() {
    return $this->hasOne('PageTranslation', 'page_id', 'id')->orderBy('language_id', 'asc');
}

public function currentTranslation() {
    return $this->hasOne('PageTranslation', 'page_id', 'id')->where('language_id', '=', Config::get('app.language_id'));
}

}

非常感谢!

编辑:

我的一个朋友向我展示了这个解决方案:

public function translation() {

if(Config::get('app.language_id')) {
    if($this->hasOne('PageTranslation', 'page_id', 'id')->where('language_id', '=', Config::get('app.language_id'))->first()) {
        return $this->hasOne('PageTranslation', 'page_id', 'id')->where('language_id', '=', Config::get('app.language_id'));
    }
}

return $this->hasOne('PageTranslation', 'page_id', 'id')->orderBy('language_id', 'asc');
}

【问题讨论】:

  • 您有什么理由在视图而不是控制器中解析 IF 吗?

标签: php laravel relationship


【解决方案1】:

你为什么不试试可以这样调用的访问器:

// $page->translation;


class Page extends Eloquent {

  public function firstTranslation() {
    return $this->hasOne('PageTranslation', 'page_id', 'id')->orderBy('language_id', 'asc');
  }

  public function currentTranslation() {
    return $this->hasOne('PageTranslation', 'page_id', 'id')->where('language_id', '=', Config::get('app.language_id'));
  }

  public function getTranslationAttribute(){
     if($this->currentTranslation) {
        return $this->currentTranslation; 
     } else {
        return $this->firstTranslation;
    }
  }

}

【讨论】:

  • 它更具可测试性,尽管我不确定在 where 条件下使用 hasOne 是否是最佳实践。
  • 它不是 - 我会选择一个范围,因为 hasOne 和其他基本上用于快速加载您的关系以防止 N+1 情况。在我看来,最好改为 SCOPE 关系,这样您就可以在控制器中进行链接。
  • 我真的很喜欢你的解决方案。非常感谢您,先生!
【解决方案2】:

在阅读了你朋友的解决方案后,我建议稍微清理一下

使用

class Page extends Eloquent {

public function translation($lang_id) {

if(isset($lang_id)) {
    if($this->hasOne('PageTranslation', 'page_id', 'id')->where('language_id', '=', $lang_id)->first()) {
        return $this->hasOne('PageTranslation', 'page_id', 'id')->where('language_id', '=', $land_id);
    }
}

return $this->hasOne('PageTranslation', 'page_id', 'id')->orderBy('language_id', 'asc');
}
}

1) 它应该从外部而不是从配置接收语言 ID,它会使您的模型无法测试。

2) isset 主要是作为我检查存在性的习惯,而不是依赖于 null 或零。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-04
    • 2011-07-17
    • 1970-01-01
    • 2017-09-09
    • 2019-03-25
    • 2021-03-21
    • 2011-07-05
    • 1970-01-01
    相关资源
    最近更新 更多