2017-04-06 41 views
10

在Laravel 5.4中,當我嘗試將用戶模型保存到數據庫時,不保存這些值。我也設置了可填寫的屬性。只有用戶模型正在使用空值保存到數據庫

它在Laravel 5.3工作。將應用程序升級到Laravel 5.4後即將出現此問題。

以下是用戶模型。

class User extends BaseModel implements AuthenticatableContract, CanResetPasswordContract, JWTSubject 
{ 
    use SoftDeletes, 
     UserAccess, 
     UserAttribute, 
     UserRelationship, 
     Authenticatable, 
     CanResetPassword, 
     Notifiable; 

    /** 
    * Database Table 
    * 
    * @var string 
    */ 
    protected $table = "users"; 

    /** 
    * The attributes that are not mass assignable. 
    * 
    * @var array 
    */ 
    protected $guarded = ['id']; 

    /** 
    * Fillable Form Fields 
    * 
    * @var array 
    */ 
    protected $fillable = [ 
     'name', 
     'first_name', 
     'last_name', 
     'email', 
     'password', 
     'status', 
     'confirmed', 
     'api_user', 
     'confirmation_code', 
     'account_id', 
     'role_id', 
     'cw_contact_id', 
     'all', 
     'all_locations', 
     'username', 
    ]; 

    /** 
    * The attributes that should be hidden for arrays. 
    * 
    * @var array 
    */ 
    protected $hidden = ['password', 'remember_token']; 

    /** 
    * Select HTML Preference 
    * 
    * @var string 
    */ 
    protected static $selectHTMLFormat = "[email]"; 

    /** 
    * @var array 
    */ 
    protected $dates = ['deleted_at', 'last_login']; 
} 

請注意問題出在用戶模型上。

我正在保存下面的用戶。

// Create User 
     $user = $this->model->create([ 
      'first_name'  => $input['first_name'], 
      'last_name'   => $input['last_name'], 
      'username'   => $input['username'], 
      'email'    => $input['email'], 
      'password'   => bcrypt($input['password']), 
      'confirmation_code' => md5(uniqid(mt_rand(), true)), 
      'confirmed'   => 1, 
      'api_user'   => (isset($input['api_user']) ? $input['api_user'] : 0), 
      'account_id'  => $input['account_id'], 
      'role_id'   => (isset($input['role_id']) ? $input['role_id'] : 0), 
      'all'    => (!isset($input['associated-permissions']) || $input['associated-permissions'] == 'all') ? 1 : 0, 
      'status'   => (!isset($input['status']) || $input['status'] ? 1 : 0), 
      'all_locations'  => $input['all_locations'] 
     ]); 

然後BaseModel的創建方法將被調用,下面是它的代碼。

public static function create(array $attributes = Array()) 
{ 
    $user = access()->user(); 

    if($user) 
    { 
     $attributes['account_id'] = (!isset($attributes['account_id']) ? $user->account->id : $attributes['account_id']); 
    } 

    $childClass  = get_called_class(); 
    $model   = new $childClass; 
    $model->runActionLogger(false, 'create'); 

    return parent::query()->create($attributes); 
} 
+0

什麼問題? –

+1

告訴我們代碼如何保存 – SteD

+0

用戶模型(沒有特徵)中的一切看起來都不錯。您可以使用try-catch塊捕獲堆棧跟蹤錯誤,並請與我們分享結果。 –

回答

1

夥計們,我能夠通過使用fill()方法來解決問題。

public static function create(array $attributes = Array()) 
{ 
    $user = access()->user(); 

    if($user) 
    { 
     $attributes['account_id'] = (!isset($attributes['account_id']) ? $user->account->id : $attributes['account_id']); 
    } 

    $childClass  = get_called_class(); 
    $model   = new $childClass; 

    $model->fill($attributes); 
    $model->save(); 

    $model->runActionLogger($model, 'create'); 

    return $model; 
} 

另外,由於我在CanResetPassword Trait中添加了構造,導致了問題。所以,如果我刪除,一切都會像以前一樣工作。

5

從5.4 create()功能沒有更多的Illuminate\Database\Eloquent\Model定義:

是爲DINAMIC方法調用處理,也就是通過調用這些函數之一(如果它是靜態或不叫dependig上) :

public static function __callStatic($method, $parameters) 
// or 
public function __call($method, $parameters) 

Illuminate\Database\Eloquent\Model類。

現在我沒有所有的代碼,但是,恕我直言,我會嘗試改變這條線在你BaseModel類:

return parent::query()->create($attributes); 

這樣:

return $model->create($attributes); 

,或者甚至更好地爲我,這樣:

return (new static)->newQuery()->create($attributes); 
+0

當我使用$ model-> create()時,它只會調用該模型的baseModel函數,但不會調用Laravel。另一種選擇不適用於用戶模型。 –

+0

試試最後一個請 – dparoli

+0

試過但沒有成功。我想這是CanResetPasswordContract的情況。如果我沒有實現它,上面的代碼將工作。 –

2

documentation 它說:

$post = App\Post::find(1); 

$comment = $post->comments()->create([ 
    'message' => 'A new comment.', 
]); 

所以

$user = $this->users()->create([ 
      'first_name'  => $input['first_name'], 
      'last_name'   => $input['last_name'], 
      'username'   => $input['username'], 
      'email'    => $input['email'], 
      'password'   => bcrypt($input['password']), 
      'confirmation_code' => md5(uniqid(mt_rand(), true)), 
      'confirmed'   => 1, 
      'api_user'   => (isset($input['api_user']) ? $input['api_user'] : 0), 
      'account_id'  => $input['account_id'], 
      'role_id'   => (isset($input['role_id']) ? $input['role_id'] : 0), 
      'all'    => (!isset($input['associated-permissions']) || $input['associated-permissions'] == 'all') ? 1 : 0, 
      'status'   => (!isset($input['status']) || $input['status'] ? 1 : 0), 
      'all_locations'  => $input['all_locations'] 
     ]); 

其中users()是你的公共職能,但我不知道什麼是你的情況$this但應該是模型作爲從示例文檔。

爲什麼你不使用資源控制器?或者,如果你需要填充數據庫使用播種機 我認爲這將是更容易管理。

+0

我不想這樣做。在記錄每個活動時,我只需要繞過它的baseModel。它與其他模型一起工作,但問題僅限於用戶模型。 –

+0

@ViralSolani你可以發佈更多的代碼,只是爲了解'$ this'是什麼? –

7

原因很可能是Laravel 5.4中稱爲「請求消毒中間件」的新中間件,如https://laravel.com/docs/5.4/releases中所述。

在app/Http/kernel.php中禁用\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,,看看你得到了什麼。

您還可以檢入/ config/database。php和你的mysql連接設置:'strict' => true,如果是的話,設置爲false

一個很好的做法是使用該模型進行用戶輸入。在這種情況下,您可以使用 $user = new \App\User($input)填充您的模型而不是$user = $this->model->create(...),並從那裏更新您的值,f.ex. $user->confirmation_code = md5(uniqid(mt_rand(), true));$user->password = bcrypt($user->password);

如果字段爲空,表明這樣的遷移文件,f.ex. $table->string('all')->nullable();

如果做到了運行$user->save();

+0

事實並非如此。中間件並非如此。以上代碼適用於所有其他型號。只是得到用戶模型的問題。 –

1

所以兩件事情我能想到

月1日,沒有必要使用

保護$守衛= [];

and

protected $ fillable = [];

守衛會認爲一切都可以填寫,如果它不在這裏,可填寫將假設一切都被守衛,除非在這裏。

引述文檔

雖然$可填寫作爲屬性應該是質量分配的「白名單」,你也可以選擇使用$把守。 $ guard守護屬性應該包含一些您不想大規模分配的屬性。數組中不包含的所有其他屬性都將是可分配的。所以,像「黑名單」這樣的警衛職能。當然,你應該使用$ fillable或$ guard - 不是兩種。

2日,以排除任何的$這個 - >模型的東西嘗試實例化類第一,並保存

use App\Path\To\Model as user; 

$user = new user(); 
$user->first_name = $input['first_name']; 
$user->last_name  = $input['last_name']; 
$user->username  = $input['username']; 
$user->email   = $input['email']; 
$user->password  = bcrypt($input['password']); 
$user->confirmation_code = md5(uniqid(mt_rand(); true)); 
$user->confirmed  = 1; 
$user->api_user  = (isset($input['api_user']) ? $input['api_user'] : 0); 
$user->account_id = $input['account_id']; 
$user->role_id  = (isset($input['role_id']) ? $input['role_id'] : 0); 
$user->all   = (!isset($input['associated-permissions']) || $input['associated-permissions'] == 'all') ? 1 : 0; 
$user->status  = (!isset($input['status']) || $input['status'] ? 1 : 0); 
$user->all_locations = $input['all_locations']; 
$user->save(); 
+0

我不想這樣做。在記錄每個活動時,我只需要繞過它的baseModel。它與其他模型一起工作,但問題僅限於用戶模型。 –

1

是的,你不能在traits中使用__construct方法。

請參考PHP.net瞭解有關特徵的更多詳細信息,他們說:「在__construct方法上使用AS(或許還有其他魔術方法)真的非常糟糕。」

你可以像下面的方式使用特質。

class User extends BaseModel 
{ 
    use userRelation 
} 

Trait userRelation 
{ 
     public function getUserName() 
     { 
      return "Jhon Doe"; 
     } 
} 

我已經創建了「userRelation」Trait,它包含幾個有用的代碼來重用。

請參考以下鏈接查看更多細節 - http://php.net/manual/en/language.oop5.traits.php

請嘗試,讓我知道,如果它不會工作。 謝謝

相關問題