【问题标题】:Laravel 4 : model assocation (belongsTo)Laravel 4:模型关联(属于 To)
【发布时间】:2014-05-08 06:59:36
【问题描述】:

我与 laravel 4 有一个非常简单的表关联:

foods table
  id
  name
  food_category_id

food_categories table
  id
  name

这是我的两个模型:

//models/Food.php         
class Food extends Eloquent {
    public function food_category()
    {
        return $this->belongsTo('FoodCategory');
    }
}


//models/FoodCategory.php
class FoodCategory extends Eloquent {

}

当尝试从 Food 模型中提取类别信息时:

在控制器中:

class FoodController extends \BaseController {
    public function index()
    {
        $foods = Food::all();
        return View::make('admin/food/index',compact('foods'));
    }
}

在视图中:

@foreach($foods as $food)
        <tr>
            <td>{{ $food->id }} </td>
            <td>{{ $food->name }}</td>
            <td>{{ $food->description}}</td>
            <td>{{ $food->price}}</td>
            <td>{{ $food->food_category->name }}</td>        
        </tr>
@endforeach

我收到以下错误消息:

试图获取非对象的属性(查看: /Library/WebServer/Documents/xxx/test/app/views/admin/food/index.blade.php)

基于dynamic properties,数据应该来自->food>category

  • 我遵循 laravel 的命名约定。
  • 数据库中存在数据

使用 dd(DB::getQueryLog()) 进行调试:

array(2) { [0]=> array(3) { ["query"]=> string(44) "select * from `users` where `id` = ? limit 1" ["bindings"]=> array(1) { [0]=> int(6) } ["time"]=> float(0.79) } [1]=> array(3) { ["query"]=> string(21) "select * from `foods`" ["bindings"]=> array(0) { } ["time"]=> float(0.32) } }

======= 更新

添加急切加载时:

$foods = Food::with('food_category')->get();

我明白了:

array(3) { [0]=> array(3) { ["query"]=> string(44) "select * from `users` where `id` = ? limit 1" ["bindings"]=> array(1) { [0]=> int(6) } ["time"]=> float(0.52) } [1]=> array(3) { ["query"]=> string(21) "select * from `foods`" ["bindings"]=> array(0) { } ["time"]=> float(0.42) } [2]=> array(3) { ["query"]=> string(67) "select * from `food_categories` where `food_categories`.`id` in (?)" ["bindings"]=> array(1) { [0]=> string(1) "1" } ["time"]=> float(3.23) } }

【问题讨论】:

  • 您是在视图中调用它吗?
  • 是的,我对所有元素使用了一个 foreach 循环 @foreach($foods as $food) 并用 {{ $food->food_category->name }} 调用它
  • 所以$food 就是Food::find(),对吧?你能发布给你错误的实际代码吗?如何在控制器中调用它以及如何/传递给视图的内容
  • 我已经更新了我的问题。谢谢
  • 你的关系没问题。您似乎没有与FoodCategory 中的一个或一些Food 模型相关的FoodCategory。还可以像建议的那样使用急切加载来避免 N+1 问题,但这里不是这种情况。您可以通过在您调用类别名称的位置添加is_null($food-&gt;food_category) 来检查

标签: php laravel eloquent model-associations


【解决方案1】:

看来你们的关系倒转了。您通过food 请求food_category。所以food 有一个food_categoryfood_category 属于food 如果这应该是hasOnehasMany 我看不到你的例子。

数据库

foods table
  id
  name

food_categories table
  id
  name
  food_id

模型/Food.php

class Food extends Eloquent {
    public function food_category()
    {
        return $this->hasOne('FoodCategory');
    }
}

模型/FoodCategory.php

class FoodCategory extends Eloquent {

}

【讨论】:

  • 谢谢。不,我的食物对象有一个 food_category_id 。示例:类别=>肉类食品=>牛肉
  • 我写的对吗?如果它不起作用,您能否更清楚地发布您想要的内容。因为这应该很容易做到! ;)
  • 我添加了我的数据库的捕获。
【解决方案2】:

尝试预加载:

$foods = Food::with('FoodCategory')->get();

【讨论】:

  • 谢谢。给我几分钟来尝试加载急切!
  • 存在急切加载以缓解 N+1 查询问题!
  • 正如 Razor 所说,eager 是为了避免多个循环,但这里并非如此。
  • 无法解释原因,但通过急切加载,它可以工作!谢谢
  • 但这只是因为您的关系现在设置正确,对吧?因为那是真正的问题。
【解决方案3】:

我认为要解决这个问题,你有两个选择:

首先:

public function category()
{
    return $this->belongsTo('FoodCategory');
}

那就更优雅的{{ $food-&gt;category-&gt;name }}

第二:只需添加'id'

public function food_category()
{
    return $this->belongsTo('FoodCategory','food_category_id');
}

【讨论】:

  • 你的第二个选项是错误的,它应该是外键作为第二个参数所以food_category_id这里可以省略
  • 谢谢。您的两个解决方案都以相同的错误结束
  • @johann 在返回视图前添加dd(DB::getQueryLog());,并添加 eagerLoading 关系以查看两个查询,让我们知道结果
  • 我已经添加了 getQueryLog(没有 eagerLoading)。 (问题已更新)谢谢
  • 我已经尝试过快速加载,但出现了一个不同的错误(问题已更新)。感谢您的帮助
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多