不确定我是不是正确使用急切加载,在存在的关系上获取 null
Posted
技术标签:
【中文标题】不确定我是不是正确使用急切加载,在存在的关系上获取 null【英文标题】:Not sure if I am using eager loading correctly, getting null on a relationship that exists不确定我是否正确使用急切加载,在存在的关系上获取 null 【发布时间】:2014-09-14 01:03:36 【问题描述】:我在处理这个雄辩的问题时遇到了困难,希望有人能帮助我。
除了作者关系之外,查询工作正常,当我知道作者和关系都存在时,它返回 null。 (数据库中没有没有作者的书)
这里是有问题的代码:
// BookController.php
$categories = array(1,2,3,4);
$audience_age = 15;
$books = Book::with(array('categories','author'))->whereHas('categories', function($q) use ($categories, $audience_age)
$q->whereIn('id', $categories)->where('audience_age', '<=', $audience_age)->where('status', '=', 'active');
)->take(50)->get(array('id','data'));
// Book.php
public function author()
return $this->belongsTo('Author');
// Author.php
public function books()
return $this->hasMany('Book');
// authors migration
Schema::create('authors', function($table)
$table->increments('id');
$table->string('name');
$table->string('status');
$table->timestamps();
$table->softDeletes();
);
// books migration
Schema::create('books', function($table)
$table->increments('id');
$table->integer('author_id')->unsigned();
$table->foreign('author_id')->references('id')->on('authors');
$table->string('name');
$table->text('data');
$table->string('status');
$table->timestamps();
$table->softDeletes();
);
我通过选择一本书 ID#40 验证了这种关系确实存在并且有效,并单独运行了这个查询:
print_r(Book::find(40)->author->toJSON());
这样加载时发现作者没有问题。
我已经使用我疯狂的 googl'in 技能几个小时试图弄清楚这一点,但到目前为止什么都没有......非常感谢任何帮助!
更新 --
查看DB::getQueryLog()后发现查询中作者的ID设置为0
["query"]=> string(55) "select * from authors
where authors
.id
in (?)" ["bindings"]=> array(1) [0]=> int( 0)
【问题讨论】:
更简单的方法是打印出后台生成的 SQL 语句。你能打印出 DB::getQueryLog() 看看 Eloquent 产生了什么吗? 调用它如何在关系中返回null
?
在Author查询中好像没有设置作者的ID,设置为0:select * from authors
where authors
.id
in (?)" [ "绑定"]=> 数组(1) [0]=> int(0)
通常,如果我渴望加载多个关系,我只需传递一个模型字符串,即 with('categories', 'author'),你是否尝试过不使用数组?
是的,我确实尝试过。查询双向工作,但仍不返回作者
【参考方案1】:
你的代码唯一的问题是没有得到foreign key
链接Book
和Author
:
$books = Book:: ... ->get(array('id','data'));
这样 Eloquent 不知道要查找什么,因此它设置了合理的默认值 0
。
只需将author_id
包含在select
中:
$books = Book:: ... ->get(array('id', 'data', 'author_id'));
它会按预期工作。
【讨论】:
6 个月后,我遇到了同样的问题,您的回答再次帮助了我。会再次 +1【参考方案2】:我不知道如何使用 ORM,但我能够使用 DB::raw 使查询正常工作。
如果我知道如何让它在 ORM 中工作,我会回来更新我的答案。
现在,我是这样完成的:
$results = DB::select(DB::raw("SELECT b.id, b.data, au.id as author_id, GROUP_CONCAT(c.id) as categories
FROM books b
INNER JOIN book_category bc ON bc.book_id = b.id
INNER JOIN categories c ON c.id = bc.category_id
INNER JOIN authors au ON au.id = b.author_id
WHERE c.id IN (1,2,3,4)
LIMIT 2"));
【讨论】:
以上是关于不确定我是不是正确使用急切加载,在存在的关系上获取 null的主要内容,如果未能解决你的问题,请参考以下文章