Laravel: 更新用户最早的token
Laravel: update the oldest token of user
我目前正在使用 Lumen 创建 API。例如,我有 2 tables users
和 users_token
以及相应的模型 User
和 UsersToken
:
App\User:
<?php
namespace App;
use Illuminate\Auth\Authenticatable;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Database\Eloquent\Model;
use Laravel\Lumen\Auth\Authorizable;
class User extends Model implements AuthenticatableContract, AuthorizableContract
{
use Authenticatable, Authorizable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name',
'email',
'firstname',
'password'
];
/**
* The attributes excluded from the model's JSON form.
*
* @var array
*/
protected $hidden = [
'id',
'password',
'email_verified_at'
];
public function tokens()
{
return $this->hasMany('App\UsersToken', 'user_id');
}
}
App\UsersToken:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class UsersToken extends Model
{
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'users_token';
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'user_id',
'token',
];
}
table users_token
有 2 个重要字段:user_id
(与 users
table 中的 id
字段链接的外键)和token
(一个简单的字符串)。
在我的模型 User
中,我有方法 tokens
return 来自用户使用 hasMany()
函数的所有标记:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function tokens()
{
return $this->hasMany('App\UsersToken');
}
}
table users_token
还包含默认字段 created_at
和 updated_at
。因此,为了获得用户最早修改的令牌,我决定使用 Laravel:
的 oldest()
和 first()
函数
$latestUserToken = $user->tokens->oldest('updated_at')->first();
那么我只需要更新它的值 token
最后 save()
它:
$latestUserToken = $user->tokens->oldest('updated_at')->first();
$latestUserToken->token = 'test';
$latestUserToken->save();
但遗憾的是我收到此错误消息:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'id' in 'where clause' (SQL: update users_token
set token
= test, users_token
.updated_at
= 2020-04-06 17:34:59 where id
is null)
如果我制作一个 $user->tokens->oldest('updated_at')->first()
的 print_r
我得到这个:
[withCount:protected] => Array
(
)
[perPage:protected] => 15
[exists] => 1
[wasRecentlyCreated] =>
[attributes:protected] => Array
(
[user_id] => 11
[token] => IsSdh03fKS3NCpfVmfm8XZyK1uYf2hSb3nRkojo86XRN7zdZnRqEOZe2HvXT
[created_at] => 2020-04-05 17:18:22
[updated_at] => 2020-04-01 17:18:22
)
[original:protected] => Array
(
[user_id] => 11
[token] => IsSdh03fKS3NCpfVmfm8XZyK1uYf2hSb3nRkojo86XRN7zdZnRqEOZe2HvXT
[created_at] => 2020-04-05 17:18:22
[updated_at] => 2020-04-01 17:18:22
)
[changes:protected] => Array
(
)
[casts:protected] => Array
(
)
[classCastCache:protected] => Array
(
)
[dates:protected] => Array
(
)
[dateFormat:protected] =>
[appends:protected] => Array
(
)
[dispatchesEvents:protected] => Array
(
)
[observables:protected] => Array
(
)
[relations:protected] => Array
(
)
[touches:protected] => Array
(
)
[timestamps] => 1
[hidden:protected] => Array
(
)
[visible:protected] => Array
(
)
[guarded:protected] => Array
(
[0] => *
)
)
有人知道我的错误在哪里吗?
你能评论一下打印吗
$latestUserToken = $user->tokens->oldest('updated_at')->first();
我认为这是用户和 user_token 之间的混合体,因此不是要更新的明确实例。
您还可以查看 users_token table 结构(主键)。
Eloquent 不支持 复合 主键。
如果你想达到那个你应该覆盖两个方法并覆盖 $primary_key
属性。
在App\UsersToken:
class UsersToken extends Model
{
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'users_token';
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'user_id',
'token',
];
protected $primaryKey = [
'user_id',
'token',
];
/**
* Set the keys for a save update query.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Eloquent\Builder
*/
protected function setKeysForSaveQuery(\Illuminate\Database\Eloquent\Builder $query)
{
$keys = $this->getKeyName();
if (! is_array($keys)) {
return parent::setKeysForSaveQuery($query);
}
foreach ($keys as $keyName) {
$query->where($keyName, '=', $this->getKeyForSaveQuery($keyName));
}
return $query;
}
/**
* Get the primary key value for a save query.
*
* @param mixed $keyName
* @return mixed
*/
protected function getKeyForSaveQuery($keyName = null)
{
if (null === $keyName) {
$keyName = $this->getKeyName();
}
return $this->original[$keyName] ?? $this->getAttribute($keyName);
}
}
我尝试了很多不同的方法来在我的工作区中生成错误。我唯一能生成它的是 users_token
table 中没有 id
列。 users_token
table.
中似乎没有 id
列
如果未明确定义,Eloquent 将查找字段 id
作为任何 table 的主键。您可以使用 protected $primaryKey = 'token';
在模型上定义主键字段名称。我假设您希望字段 token
作为主键。
但我建议不要使用 token
作为主要。使用普通的旧自增长整数作为主键,并使用 token
作为唯一键。这将防止任何不需要的重复条目。
其余代码看起来没问题。
我目前正在使用 Lumen 创建 API。例如,我有 2 tables users
和 users_token
以及相应的模型 User
和 UsersToken
:
App\User:
<?php
namespace App;
use Illuminate\Auth\Authenticatable;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Database\Eloquent\Model;
use Laravel\Lumen\Auth\Authorizable;
class User extends Model implements AuthenticatableContract, AuthorizableContract
{
use Authenticatable, Authorizable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name',
'email',
'firstname',
'password'
];
/**
* The attributes excluded from the model's JSON form.
*
* @var array
*/
protected $hidden = [
'id',
'password',
'email_verified_at'
];
public function tokens()
{
return $this->hasMany('App\UsersToken', 'user_id');
}
}
App\UsersToken:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class UsersToken extends Model
{
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'users_token';
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'user_id',
'token',
];
}
table users_token
有 2 个重要字段:user_id
(与 users
table 中的 id
字段链接的外键)和token
(一个简单的字符串)。
在我的模型 User
中,我有方法 tokens
return 来自用户使用 hasMany()
函数的所有标记:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function tokens()
{
return $this->hasMany('App\UsersToken');
}
}
table users_token
还包含默认字段 created_at
和 updated_at
。因此,为了获得用户最早修改的令牌,我决定使用 Laravel:
oldest()
和 first()
函数
$latestUserToken = $user->tokens->oldest('updated_at')->first();
那么我只需要更新它的值 token
最后 save()
它:
$latestUserToken = $user->tokens->oldest('updated_at')->first();
$latestUserToken->token = 'test';
$latestUserToken->save();
但遗憾的是我收到此错误消息:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'id' in 'where clause' (SQL: update
users_token
settoken
= test,users_token
.updated_at
= 2020-04-06 17:34:59 whereid
is null)
如果我制作一个 $user->tokens->oldest('updated_at')->first()
的 print_r
我得到这个:
[withCount:protected] => Array
(
)
[perPage:protected] => 15
[exists] => 1
[wasRecentlyCreated] =>
[attributes:protected] => Array
(
[user_id] => 11
[token] => IsSdh03fKS3NCpfVmfm8XZyK1uYf2hSb3nRkojo86XRN7zdZnRqEOZe2HvXT
[created_at] => 2020-04-05 17:18:22
[updated_at] => 2020-04-01 17:18:22
)
[original:protected] => Array
(
[user_id] => 11
[token] => IsSdh03fKS3NCpfVmfm8XZyK1uYf2hSb3nRkojo86XRN7zdZnRqEOZe2HvXT
[created_at] => 2020-04-05 17:18:22
[updated_at] => 2020-04-01 17:18:22
)
[changes:protected] => Array
(
)
[casts:protected] => Array
(
)
[classCastCache:protected] => Array
(
)
[dates:protected] => Array
(
)
[dateFormat:protected] =>
[appends:protected] => Array
(
)
[dispatchesEvents:protected] => Array
(
)
[observables:protected] => Array
(
)
[relations:protected] => Array
(
)
[touches:protected] => Array
(
)
[timestamps] => 1
[hidden:protected] => Array
(
)
[visible:protected] => Array
(
)
[guarded:protected] => Array
(
[0] => *
)
)
有人知道我的错误在哪里吗?
你能评论一下打印吗
$latestUserToken = $user->tokens->oldest('updated_at')->first();
我认为这是用户和 user_token 之间的混合体,因此不是要更新的明确实例。
您还可以查看 users_token table 结构(主键)。
Eloquent 不支持 复合 主键。
如果你想达到那个你应该覆盖两个方法并覆盖 $primary_key
属性。
在App\UsersToken:
class UsersToken extends Model
{
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'users_token';
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'user_id',
'token',
];
protected $primaryKey = [
'user_id',
'token',
];
/**
* Set the keys for a save update query.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Eloquent\Builder
*/
protected function setKeysForSaveQuery(\Illuminate\Database\Eloquent\Builder $query)
{
$keys = $this->getKeyName();
if (! is_array($keys)) {
return parent::setKeysForSaveQuery($query);
}
foreach ($keys as $keyName) {
$query->where($keyName, '=', $this->getKeyForSaveQuery($keyName));
}
return $query;
}
/**
* Get the primary key value for a save query.
*
* @param mixed $keyName
* @return mixed
*/
protected function getKeyForSaveQuery($keyName = null)
{
if (null === $keyName) {
$keyName = $this->getKeyName();
}
return $this->original[$keyName] ?? $this->getAttribute($keyName);
}
}
我尝试了很多不同的方法来在我的工作区中生成错误。我唯一能生成它的是 users_token
table 中没有 id
列。 users_token
table.
id
列
如果未明确定义,Eloquent 将查找字段 id
作为任何 table 的主键。您可以使用 protected $primaryKey = 'token';
在模型上定义主键字段名称。我假设您希望字段 token
作为主键。
但我建议不要使用 token
作为主要。使用普通的旧自增长整数作为主键,并使用 token
作为唯一键。这将防止任何不需要的重复条目。
其余代码看起来没问题。