【问题标题】:PHP: Slim Framework/Eloquent ORM mass assignment errorPHP:Slim Framework/Eloquent ORM 批量分配错误
【发布时间】:2016-01-02 02:05:52
【问题描述】:

我在 laravel 之外使用 eloquent 和苗条的框架,我有控制器可以帮助执行 CRUD 操作。当我尝试执行批量赋值操作时,Eloquent 会抛出一个错误:

SQLSTATE[23000]: Integrity constraint violation: 19 NOT NULL constraint failed:
 emoji.name (SQL: insert into "emoji" ("user_id", "updated_at", "created_at") 
values (1, 2016-01-02 02:56:43, 2016-01-02 02:56:43))

Bellow 是我的控制器和模型:

public function create(ServerRequestInterface $request, ResponseInterface $response)
{
    $data   =   $request->getParsedBody();
    $uid    =   $data['uid'];
    $keywords   =   $data['keywords'];

    $body   =   $response->getBody();

        $user   =   User::find($uid);
        $user->emojis()->create([
            'name'  =>  $data['name'],
            'char'  =>  $data['char'],
            'category'  =>  $data['category'],
        ]);
//            $emoji = new Emoji();
//            $emoji->name  =  $data['name'];
//            $emoji->char  =  $data['char'];
//            $emoji->category  =  $data['category'];
//            $emoji->save();
        return $response;
    }

当我使用上面注释的行时,应用程序可以工作,但其他行不行:

我的模型如下:

namespace BB8\Emoji\Models;
use BB8\Emoji\Models\BaseModel;

class Emoji  extends BaseModel
{
    protected $table    = 'emoji';
    protected $dates    = ['created_at', 'updated_at', 'deleted_at'];
    protected $fillable = array('name', 'char', 'category', 'created_at', 'updated_at', 'user_id');

public function user()
{
    return $this->belongsTo("BB8\Emoji\Models\User");
}

public function keywords()
{
    return $this->hasMany("BB8\Emoji\Models\EmojiKeyword");
}
}

当我var_dump($data) 我得到以下信息:

array (size=6)
  'name' => string 'Happy Face' (length=10)
  'char' => string ')' (length=1)
  'keywords' => 
    array (size=1)
      0 => string 'happy' (length=5)
  'category' => string 'Happy' (length=5)
  'created_by' => int 1
  'uid' => int 1

下面是我的用户模型

namespace BB8\Emoji\Models;
use BB8\Emoji\Models\BaseModel;
class User extends BaseModel
{
public $timestamps = false;
protected $fillable = ['username', 'password', 'jit'];

public function emojis()
{
    return $this->hasMany('BB8\Emoji\Models\Emoji');
}

public static function auth($username, $password)
{
    $user       =   static::where('username', '=', $username)->first();

    if (isset($user->exists) && $user->exists) {
        if (strcmp(hash('sha256', $password), $user->password) == 0) {
            return $user;
        }
    }

    return false;
}



  public static function isAuthenticated($token)
    {
    }
  }

BaseModel.php:

 namespace BB8\Emoji\Models;
use BB8\Emoji\Database\Connection;

class BaseModel extends \Illuminate\Database\Eloquent\Model
{
    public function __construct()
    {
        $dotenv = new \Dotenv\Dotenv(__DIR__.'/../../');
        $dotenv->load();
    }
}

我对我的代码进行了多次三重检查,但没有发现有什么问题,但它引发了违反约束的错误。这是雄辩的错误还是我做错了什么。

【问题讨论】:

  • $uid = $data['uid'];
  • @manshu 是的,我其实是用它来调试的,但我认为它不会改变任何东西,user_id是通过user->emojis()->create()的关系填充的跨度>
  • @ErenArdahan 我检查了数据库并且没有遗漏任何字段,当我将所有字段更改为允许为空时,它仅插入 user_id、created_date 和 updated_date,这意味着其他数据通过数组传递未在 create 方法中捕获
  • @ErenArdahan 我在问题中添加了 var_dump $data 时的值,有实际值并且 $data['name'] 不为空
  • 听起来不错,休息一下总是有帮助的。但是,只是为了明天一试。 laravel.io/bin/PXNRk

标签: php laravel eloquent mass-assignment


【解决方案1】:

看起来你的BaseModel 是问题所在。尝试将您的构造函数更改为:

public function __construct(array $attributes = [])
{
    $dotenv = new \Dotenv\Dotenv(__DIR__.'/../../');
    $dotenv->load();

    parent::__construct($attributes);
}

解释:

这是 Laravel 原始模型的构造函数。

public function __construct(array $attributes = [])
{
    $this->bootIfNotBooted();

    $this->syncOriginal();

    $this->fill($attributes);
}

它接受一个属性数组并用它做一些事情,但请记住fill 方法。

现在,您正在执行以下操作来创建表情符号:

$user->emojis()->create([
    'name'  =>  $data['name'],
    'char'  =>  $data['char'],
    'category'  =>  $data['category'],
]);

这会调用HasMany 类的create 方法。除了您要关注的代码行之外,我删除了所有代码:

public function create(array $attributes)
{
    ...

    $instance = $this->related->newInstance($attributes);

    ...
}

这基本上会创建模型的新实例并传入属性数组。基本上是这样的:

new Emoji([
    'name'  =>  $data['name'],
    'char'  =>  $data['char'],
    'category'  =>  $data['category'],
]);

但是,您的构造函数不接受像 Laravel 模型这样的属性数组,这会改变模型的实际行为。这些值没有被填充。顶部的解决方案应该可以解决您的问题。加载环境变量后,它只是推迟到 Laravel 的默认行为。

【讨论】:

  • 哇,天哪,我现在想哭,非常感谢......非常感谢......我完全忽略了调用父构造函数......你是太棒了
  • 哈哈,没问题。 :)
猜你喜欢
  • 1970-01-01
  • 2012-08-17
  • 1970-01-01
  • 2014-09-06
  • 2012-09-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多