自动注入的Laravel模型没有属性

时间:2017-03-01 22:13:52

标签: php laravel laravel-5 dependency-injection laravel-eloquent

我是Laravel的新手。我已经为我的一个表创建了一个模型,一个资源控制器和一个路由,我已经修改了模型类以使用特定的表名,但是Laravel 5.4注入的模型对象没有属性,即使存在相应的记录数据库。以下是我采取的步骤。

1)用工匠创建模型。我运行了这个命令:

php artisan make:model Tree

2)将树模型类修改为instructed以指定特定表。我不得不这样做,因为我的桌子被命名为,而不是"树"正如Laravel根据其内部规则所假设的那样。

/**
 * The table associated with the model.
 *
 * @var string
 */
protected $table = 'tree';

3)使用此命令创建一个使用我的模型的资源控制器

php artisan make:controller CategoryController --resource --model=Tree

4)添加资源路由routes / web.php,以便将Web服务器路径映射到控制器上:

Route::resource('categories', 'CategoryController');

5)将CategoryController的 show()方法修改为var_dump注入的$ tree对象。它看起来像这样:

/**
 * Display the specified resource.
 *
 * @param  \App\Tree  $tree
 * @return \Illuminate\Http\Response
 */
public function show(Tree $tree)
{
    // we need to display the children of $tree
    var_dump($tree);

}

6)我的表结构遵循Laravel文档的所有约定specified。有一个整数 id 列是未签名的&自动递增。我有created_at和updated_at时间戳。唯一不同的是表名是" tree"而不是"树",但这应该包含在我上面做出的改变:

CREATE TABLE IF NOT EXISTS `tree` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `parent_id` int(10) unsigned DEFAULT NULL,
  `label` varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
  `display_order` int(11) unsigned NOT NULL DEFAULT '0',
  `forum_id` int(5) NOT NULL DEFAULT '0',
  `url` varchar(128) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
  `flavor` tinyint(4) NOT NULL DEFAULT '0',
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `parent_pkey` (`parent_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

此表包含数据。它绝对是有一个id = 1的记录。

7)我访问了应该激活资源控制器的show()方法的url。输出我得到的证实,这实际上是方法CategoryController :: show()。 http://example.com/categories/1

这是问题所在。

var_dump($ tree)的输出没有属性。没有错误,但注入的对象有问题

object(App\Tree)#217 (24) {
  ["table":protected]=>
  string(4) "tree"
  ["connection":protected]=>
  NULL
  ["primaryKey":protected]=>
  string(2) "id"
  ["keyType":protected]=>
  string(3) "int"
  ["incrementing"]=>
  bool(true)
  ["with":protected]=>
  array(0) {
  }
  ["perPage":protected]=>
  int(15)
  ["exists"]=>
  bool(false)
  ["wasRecentlyCreated"]=>
  bool(false)
  ["attributes":protected]=>
  array(0) {
  }
  ["original":protected]=>
  array(0) {
  }
  ["casts":protected]=>
  array(0) {
  }
  ["dates":protected]=>
  array(0) {
  }
  ["dateFormat":protected]=>
  NULL
  ["appends":protected]=>
  array(0) {
  }
  ["events":protected]=>
  array(0) {
  }
  ["observables":protected]=>
  array(0) {
  }
  ["relations":protected]=>
  array(0) {
  }
  ["touches":protected]=>
  array(0) {
  }
  ["timestamps"]=>
  bool(true)
  ["hidden":protected]=>
  array(0) {
  }
  ["visible":protected]=>
  array(0) {
  }
  ["fillable":protected]=>
  array(0) {
  }
  ["guarded":protected]=>
  array(1) {
    [0]=>
    string(1) "*"
  }
}

我做错了什么吗?如何让Laravel注入正确的物体?

编辑:有人问为什么我在我的路线中注入了错误的物体。以下是在步骤#3中自动生成的类的缩写版本。它清楚地引用了Tree类和它期望树对象的代码提示。除了var_dump语句之外,我没有创建任何此代码。这完全是由工匠命令自动生成的,完全按照文档的指示。

namespace App\Http\Controllers;

use App\Tree;
use Illuminate\Http\Request;

class CategoryController extends Controller
{

    /**
     * Display the specified resource.
     *
     * @param  \App\Tree  $tree
     * @return \Illuminate\Http\Response
     */
    public function show(Tree $tree)
    {
        // we need to display the children of $tree
        var_dump($tree);

    }

}

3 个答案:

答案 0 :(得分:2)

路由模型绑定有一个命名约定。

尝试将操作调用更改为:

public function show(Tree $category)
{
    var_dump($category);
}

<强>更新 我查看了源代码,您还可以在资源路径声明中更改参数名称:

Route::resource('categories', 'CategoryController', ['parameters'=>['categories'=>'tree']]);

在动作调用中使用$ tree变量

public function show(Tree $tree)

答案 1 :(得分:0)

问题出在资源路由上。将您的路由替换为

Route::resource('category', 'CategoryController');

此处,路由名称必须与控制器名称完全匹配。那是问题。

答案 2 :(得分:0)

我也遇到了这个问题。 Laravel将遵循约定命名参数。

例如您的模型是

AwesomeCategory

然后AwesomeCategoryController中自动生成的编辑方法将如下所示

public function edit(AwesomeCategory $awesomeCategory) // This will not load any attributes

更改为

public function edit(AwesomeCategory $awesomecategory) // This will be automatically loaded with all attributes