在Laravel 4.1中使用Eloquent ORM查询同一表中的关系。

3

我刚开始接触 Laravel,并开始使用 Eloquent ORM。但是我遇到了一个小问题,如下所示。

我有三个表,其结构和数据如下:

words

id | language_id | parent_id | word
-------------------------------------------
1  | 1           | 0         | Welcome
-------------------------------------------
2  | 2           | 1         | Bienvenue
-------------------------------------------

documents

id | title
---------------------
1  | Hello World
---------------------

documents_words

document_id | word_id
--------------------------
1           | 1
--------------------------

正如您所看到的,我们在单词表中有一个父子关系。

文档模型定义如下

class Documents extends Eloquent {

protected $table = 'documents';

public function words()
{
    return $this->belongsToMany('Word', 'documents_words', 'document_id');
}

}

而这个词“模型”:

class Word extends Eloquent {

protected $table = 'words';

public function translation()
{
    return $this->hasOne('Word', 'parent_id');
}


}

现在我的问题是,我想检索已翻译的单词的文档,所以我认为这样做可以:

$documents = Documents::whereHas('words', function($q)
{
    $q->has('translation');
})
->get();

但是我得到了0个结果,于是我检查了Eloquent生成和使用的查询语句:
 select * from `prefix_documents`
 where
 (
select count(*) from 
`prefix_words`

inner join `prefix_documents_words` 

on `prefix_words`.`id` = `prefix_documents_words`.`word_id` 

where `prefix_documents_words`.`document_id` = `prefix_documents`.`id` 

and (select count(*) 
from `prefix_words` 
where `prefix_words`.`parent_id` = `prefix_words`.`id`) >= 1

  ) >= 1

问题在于它没有使用表的别名,我的查询应该更像这样才能工作(而且它确实可以):
 select * from `prefix_documents`
 where
 (
select count(*) from 
`prefix_words`

inner join `prefix_documents_words` 

on `prefix_words`.`id` = `prefix_documents_words`.`word_id` 

where `prefix_documents_words`.`document_id` = `prefix_documents`.`id` 

and (select count(*) 
from `prefix_words` as `w`
where `w`.`parent_id` = `prefix_words`.`id`) >= 1

  ) >= 1

但我如何使用Eloquent ORM实现这一点?

非常感谢你们的帮助,希望我的表述足够清晰。

1个回答

5
在 Word 模型中,更改该内容。
public function translation()
{
    return $this->hasOne('Word', 'parent_id');
}

public function translation()
{
    return $this->belongsToMany('Word', 'words', 'id', 'parent_id');
}

这样我们告诉 Laravel 在使用查询时在 eloquent 中创建别名。我没有测试其他情况,但我认为它会起作用。


你在数据库配置文件中设置了表前缀吗?“prefix”是我在配置中设置的。 - Gabor
如果您在数据库配置中设置了“前缀”,则默认行为是所有表名都必须在前面加上前缀,例如:prefixdocuments、prefixwords。因此,您还需要在Eloquent模型中进行更改。 - diegofelix
嗯,这对我来说似乎不太对。我使用迁移创建了表,并且在现在之前没有任何与模型相关的问题,而且我从未在除database.php配置文件以外的任何地方提到过前缀。此外,我在配置文件中设置了'prefix_',而不仅仅是'prefix'。 - Gabor
尝试移除前缀。仅创建别名具有前缀_非常奇怪。我在Laravel的新安装中完成了这个。我建议您也这样做,以确保安全。 - diegofelix
我还确认已删除旧表,在database.php配置文件中删除了前缀,重新创建了我的表,并且生成的查询正常工作!因此,看起来问题确实是在Eloquent ORM设置前缀时生成查询字符串的方式上。 - Gabor
我已经接受了你的答案,因为你解决了我的主要问题,现在似乎我的表格和表格前缀存在问题。谢谢! - Gabor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接