Php 拉维尔扩展关系
我正在从事一个有多种语言版本的laravel项目。(或者至少应该有) 例如,我有一个页面模型和一个页面翻译模型。页面翻译模型的每个实例都是一种单一的语言变体 页面模型中定义了两种关系currentTranslation和firstTranslation。如果页面没有当前语言的翻译(currentTranslation从url获取部分内容),则使用firstTranslation 解决这个问题。鉴于此,我必须编写如下条件:Php 拉维尔扩展关系,php,laravel,relationship,Php,Laravel,Relationship,我正在从事一个有多种语言版本的laravel项目。(或者至少应该有) 例如,我有一个页面模型和一个页面翻译模型。页面翻译模型的每个实例都是一种单一的语言变体 页面模型中定义了两种关系currentTranslation和firstTranslation。如果页面没有当前语言的翻译(currentTranslation从url获取部分内容),则使用firstTranslation 解决这个问题。鉴于此,我必须编写如下条件: if($page->currentTranslation) {
if($page->currentTranslation) {
$pageTranslation = $page->currentTranslation;
} else {
$pageTranslation = $page->firstTranslation;
}
而不是使用它。写这篇文章真的很烦人。我想要一个名为translation的关系,它将决定是使用currentTranslation还是firstTranslation关系。
我将在该关系内部执行一个简单的查询,但此时,页面id不可用
你能给我一个解决办法吗
我的第二个问题是:如果上面提到的问题是可以解决的,是否有可能以某种方式将数据从$page->translation
传递到$page
,因此我不必写$page->translation->title
,而只写$page->title
(它将以当前使用的语言返回页面标题)
页面模型
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');
}
为什么不尝试一个可以这样调用的访问器:
// $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;
}
}
}
在阅读了你朋友的解决方案后,我会建议你稍微清理一下 以及使用
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或零 为什么要在视图中而不是控制器中解析IF?它更易于测试,虽然我不确定在条件中的where中使用hasOne是否是一种最佳实践。但事实并非如此——我会选择一个范围,因为hasOne和其他工具基本上用于快速加载您的关系,以防止出现N+1情况。在我看来,最好是确定关系的范围,这样可以使您在控制器内建立连锁关系。我非常喜欢您的解决方案。非常感谢你,先生!