数据库:性状
- Hashable
- Purgeable
- Encryptable
- Sluggable
- Revisionable
- Sortable
- HasSortableRelations
- 简单的树
- 嵌套树
- Validation
- 软删除
- Nullable
模型特征用于实现通用功能。
Hashable
当属性首次在模型上设置时,散列属性会立即散列。要散列模型中的属性,请应用Winter\Storm\Database\Traits\Hashable
特征并声明一个$hashable
带有包含要散列的属性的数组的属性。
class User extends Model
{
use \Winter\Storm\Database\Traits\Hashable;
/**
* @var array List of attributes to hash.
*/
protected $hashable = ['password'];
}
Purgeable
创建或更新模型时,清除的属性不会保存到数据库中。要清除模型中的属性,请应用Winter\Storm\Database\Traits\Purgeable
特征并声明一个$purgeable
属性与包含要清除的属性的数组。
class User extends Model
{
use \Winter\Storm\Database\Traits\Purgeable;
/**
* @var array List of attributes to purge.
*/
protected $purgeable = ['password_confirmation'];
}
保存模型时将清除定义的属性,然后再模型事件 被触发,包括验证。使用getOriginalPurgeValue
找到一个被清除的值。
return $user->getOriginalPurgeValue('password_confirmation');
Encryptable
类似于可哈希特征,加密属性在设置时加密,但在检索属性时解密。要加密模型中的属性,请应用Winter\Storm\Database\Traits\Encryptable
特征并声明一个$encryptable
属性与包含要加密的属性的数组。
class User extends Model
{
use \Winter\Storm\Database\Traits\Encryptable;
/**
* @var array List of attributes to encrypt.
*/
protected $encryptable = ['api_key', 'api_secret'];
}
NOTE: 作为加密/解密过程的一部分,加密属性将被序列化和反序列化。不要使属性是
encryptable
还jsonable
同时作为jsonable
进程将尝试解码一个已经被加密器反序列化的值。
Sluggable
Slug 是页面 URL 中常用的有意义的代码。要为您的模型自动生成一个独特的 slug,请应用Winter\Storm\Database\Traits\Sluggable
特征并声明一个$slugs
财产。
class User extends Model
{
use \Winter\Storm\Database\Traits\Sluggable;
/**
* @var array Generate slugs for these attributes.
*/
protected $slugs = ['slug' => 'name'];
}
这$slugs
property 应该是一个数组,其中键是 slug 的目标列,值是用于生成 slug 的源字符串。在上面的例子中,如果name
列设置为Cheyenne, 结果slug
列将设置为cheyenne,cheyenne-2, 或者cheyenne-3等,然后再创建模型。
要从多个来源生成 slug,请将另一个数组作为源值传递:
protected $slugs = [
'slug' => ['first_name', 'last_name']
];
source 值还支持使用点符号从关系的属性生成 slug:
protected $slugs = [
'slug' => ['first_name', 'family.last_name']
];
仅在首次创建模型时才会生成 Slug。要覆盖或禁用此功能,只需手动设置 slug 属性:
$user = new User;
$user->name = 'Remy';
$user->slug = 'custom-slug';
$user->save(); // Slug will not be generated
使用slugAttributes
更新模型时重新生成 slug 的方法:
$user = User::find(1);
$user->slug = null;
$user->slugAttributes();
$user->save();
具有 SoftDelete 特性的 Sluggable
默认情况下,生成 slug 时会忽略软删除模型。 您可能希望在恢复软删除模型时防止 slug 重复。
设置$allowTrashedSlugs
归于true
为了在生成新的 slug 时考虑到软删除的记录。
protected $allowTrashedSlugs = true;
Revisionable
Winter模型可以通过存储修订来记录值的变化历史。要存储模型的修订,请应用Winter\Storm\Database\Traits\Revisionable
特征并声明一个$revisionable
属性和一个数组,其中包含要监视更改的属性。您还需要定义一个$morphMany
模型关系 称为revision_history
那指的是System\Models\Revision
类名revisionable
,这是存储修订历史数据的地方。
class User extends Model
{
use \Winter\Storm\Database\Traits\Revisionable;
/**
* @var array Monitor these attributes for changes.
*/
protected $revisionable = ['name', 'email'];
/**
* @var array Relations
*/
public $morphMany = [
'revision_history' => ['System\Models\Revision', 'name' => 'revisionable']
];
}
默认情况下将保留 500 条记录,但是可以通过声明$revisionableLimit
具有新限制值的模型属性。
/**
* @var int Maximum number of revision records to keep.
*/
public $revisionableLimit = 8;
修订历史可以像任何其他关系一样访问:
$history = User::find(1)->revision_history;
foreach ($history as $record) {
echo $record->field . ' updated ';
echo 'from ' . $record->old_value;
echo 'to ' . $record->new_value;
}
修订记录可选地支持使用的用户关系user_id
属性。你可以包括一个getRevisionableUser
模型中的方法来跟踪进行修改的用户。
public function getRevisionableUser()
{
return BackendAuth::getUser()->id;
}
Sortable
排序后的模型将存储一个数字值sort_order
它维护集合中每个单独模型的排序顺序。要为您的模型存储排序顺序,请应用Winter\Storm\Database\Traits\Sortable
特征并确保您的模式定义了一个列供其使用(例如:$table->integer('sort_order')->default(0);
).
class User extends Model
{
use \Winter\Storm\Database\Traits\Sortable;
}
您可以通过定义SORT_ORDER
持续的:
const SORT_ORDER = 'my_sort_order_column';
使用setSortableOrder
方法在单个记录或多个记录上设置订单。
// Sets the order of the user to 1...
$user->setSortableOrder($user->id, 1);
// Sets the order of records 1, 2, 3 to 3, 2, 1 respectively...
$user->setSortableOrder([1, 2, 3], [3, 2, 1]);
NOTE: 如果将此特征添加到先前已存在数据(行)的模型中,则可能需要先初始化数据集,然后此特征才能正常工作。为此,要么手动更新每一行的
sort_order
列或对数据运行查询以复制记录的id
列到sort_order
专栏(例如UPDATE myvendor_myplugin_mymodelrecords SET sort_order = id
).
简单的树
一个简单的树模型将使用parent_id
column 维护模型之间的父子关系。要使用简单树,请应用Winter\Storm\Database\Traits\SimpleTree
特征。
class Category extends Model
{
use \Winter\Storm\Database\Traits\SimpleTree;
}
这个特性会自动注入两个模型关系 称为parent
和children
,它等同于以下定义:
public $belongsTo = [
'parent' => ['User', 'key' => 'parent_id'],
];
public $hasMany = [
'children' => ['User', 'key' => 'parent_id'],
];
您可以通过定义PARENT_ID
持续的:
const PARENT_ID = 'my_parent_column';
使用此特征的模型集合将返回Winter\Storm\Database\TreeCollection
这增加了toNested
方法。要构建预先加载的树结构,请返回具有预先加载的关系的记录。
Category::all()->toNested();
Rendering
为了渲染所有级别的项目及其子项,您可以使用递归处理
{% macro renderChildren(item) %}
{% import _self as SELF %}
{% if item.children is not empty %}
<ul>
{% for child in item.children %}
<li>{{ child.name }}{{ SELF.renderChildren(child) | raw }}</li>
{% endfor %}
</ul>
{% endif %}
{% endmacro %}
{% import _self as SELF %}
{{ SELF.renderChildren(category) | raw }}
嵌套树
这嵌套集模型 是一种维护模型之间层次结构的高级技术,使用parent_id
,nest_left
,nest_right
, 和nest_depth
列。
$table->integer('parent_id')->nullable();
$table->integer('nest_left')->nullable();
$table->integer('nest_right')->nullable();
$table->integer('nest_depth')->nullable();
要使用嵌套集模型,请应用Winter\Storm\Database\Traits\NestedTree
特征。的所有功能SimpleTree
特征在这个模型中是固有的。
class Category extends Model
{
use \Winter\Storm\Database\Traits\NestedTree;
}
您可以通过在模型上定义以下常量来更改使用的列名称:
const PARENT_ID = 'my_parent_column';
const NEST_LEFT = 'my_left_column';
const NEST_RIGHT = 'my_right_column';
const NEST_DEPTH = 'my_depth_column';
一般接入方式:
-
$model->getRoot();
- 返回节点的最高父节点。 -
$model->getRootList();
- 从根返回一个缩进的键和值列数组。 -
$model->getParent();
- 直接父节点。 -
$model->getParents();
- 返回树上的所有父母。 -
$model->getParentsAndSelf();
- 返回树上的所有父母和自己。 -
$model->getChildren();
- 所有直接子节点的集合。 -
$model->getSiblings();
- 返回所有兄弟姐妹(父母的孩子)。 -
$model->getSiblingsAndSelf();
- 返回所有兄弟姐妹和自己。 -
$model->getLeaves();
- 返回所有没有孩子的最终节点。 -
$model->getDepth();
- 返回当前节点的深度。 -
$model->getChildCount();
- 返回所有孩子的数量。
查询构建器方法:
-
$query->withoutNode();
- 从结果中过滤特定节点。 -
$query->withoutSelf();
- 从结果中过滤当前节点。 -
$query->withoutRoot();
- 从结果中过滤根。 -
$query->children();
- 过滤器作为树下的直接子项。 -
$query->allChildren();
- 过滤树下的所有孩子。 -
$query->parent();
- 过滤器作为树的直接父级。 -
$query->parents();
- 过滤树上的所有父母。 -
$query->siblings();
- 过滤为所有兄弟姐妹(父母的孩子)。 -
$query->leaves();
- 过滤为所有没有孩子的最终节点。 -
$query->getNested();
- 返回预先加载的结果集合。 -
$query->listsNested();
- 返回键和值列的缩进数组。
平面结果获取方式:
-
$model->getAll();
- 以正确的顺序返回所有内容。 -
$model->getAllRoot();
- 返回所有根节点。 -
$model->getAllChildren();
- 返回树下的所有孩子。 -
$model->getAllChildrenAndSelf();
- 返回所有孩子和自己。
急切加载的访问方法:
-
$model->getEagerRoot();
- 返回所有根节点的列表,带有 ->children eager loaded。 -
$model->getEagerChildren();
- 返回直接子节点,带有 ->children eager loaded。
创建根节点
默认情况下,所有节点都创建为根节点:
$root = Category::create(['name' => 'Root category']);
或者,您可能会发现自己需要将现有节点转换为根节点:
$node->makeRoot();
你也可以取消它的parent_id
与“makeRoot”相同的列。
$node->parent_id = null;
$node->save();
插入节点
您可以通过关系直接插入新节点:
$child1 = $root->children()->create(['name' => 'Child 1']);
或者使用makeChildOf
现有节点的方法:
$child2 = Category::create(['name' => 'Child 2']);
$child2->makeChildOf($root);
删除节点
当一个节点被删除时delete
方法,该节点的所有后代也将被删除。注意删除模型事件 不会为子模型解雇。
$child1->delete();
获取节点的嵌套层级
这getLevel
方法将返回节点的当前嵌套级别或深度。
// 0 when root
$node->getLevel()
移动节点
有几种移动节点的方法:
-
moveLeft()
:找到左边的兄弟并移动到它的左边。 -
moveRight()
: 找到正确的兄弟并移动到它的右边。 -
moveBefore($otherNode)
: 移动到...左边的节点 -
moveAfter($otherNode)
: 移动到...右侧的节点 -
makeChildOf($otherNode)
:使节点成为...的子节点 -
makeRoot()
: 使当前节点成为根节点。
Validation
Winter模型使用内置验证器类.验证规则在模型类中定义为名为$rules
并且班级必须使用特征Winter\Storm\Database\Traits\Validation
:
class User extends Model
{
use \Winter\Storm\Database\Traits\Validation;
public $rules = [
'name' => 'required|between:4,16',
'email' => 'required|email',
'password' => 'required|alpha_num|between:4,8|confirmed',
'password_confirmation' => 'required|alpha_num|between:4,8'
];
}
NOTE: 你可以自由使用数组语法 验证规则也是如此。
class User extends Model
{
use \Winter\Storm\Database\Traits\Validation;
public $rules = [
'links.*.url' => 'required|url',
'links.*.anchor' => 'required'
];
}
模型在save
方法被调用。
$user = new User;
$user->name = 'Actual Person';
$user->email = 'a.person@example.com';
$user->password = 'passw0rd';
// Returns false if model is invalid
$success = $user->save();
NOTE:您还可以随时使用
validate
方法。
检索验证错误
当模型验证失败时,Illuminate\Support\MessageBag
对象附加到模型。包含验证失败消息的对象。检索验证错误消息集合实例errors
方法或$validationErrors
财产。检索所有验证错误errors()->all()
.检索错误specific 属性使用validationErrors->get('attribute')
.
NOTE: 该模型利用 MessagesBag 对象,该对象具有简单而优雅的方法 格式错误。
覆盖验证
这forceSave
方法验证模型并保存,无论是否存在验证错误。
$user = new User;
// Creates a user without validation
$user->forceSave();
自定义错误消息
就像 Validator 类一样,您可以使用相同的语法.
class User extends Model
{
public $customMessages = [
'required' => 'The :attribute field is required.',
...
];
}
您还可以将自定义错误消息添加到验证规则的数组语法中。
class User extends Model
{
use \Winter\Storm\Database\Traits\Validation;
public $rules = [
'links.*.url' => 'required|url',
'links.*.anchor' => 'required'
];
public $customMessages = [
'links.*.url.required' => 'The url is required',
'links.*.url.*' => 'The url needs to be a valid url',
'links.*.anchor.required' => 'The anchor text is required',
];
}
在上面的示例中,您可以将自定义错误消息写入特定的验证规则(这里我们使用:required
).或者你可以使用*
选择其他所有内容(这里我们向url
验证规则使用*
).
自定义属性名称
您还可以使用$attributeNames
大批。
class User extends Model
{
public $attributeNames = [
'email' => 'Email Address',
...
];
}
动态验证规则
您可以通过覆盖beforeValidate
模型事件 方法。在这里我们检查是否is_remote
属性是false
然后动态设置latitude
和longitude
属性为必填字段。
public function beforeValidate()
{
if (!$this->is_remote) {
$this->rules['latitude'] = 'required';
$this->rules['longitude'] = 'required';
}
}
自定义验证规则
您还可以创建自定义验证规则同样的方式 你会为 Validator 服务。
软删除
软删除模型时,它实际上并没有从数据库中删除。相反,一个deleted_at
记录上设置了时间戳。要为模型启用软删除,请应用Winter\Storm\Database\Traits\SoftDelete
模型的特征并将 deleted_at 列添加到您的$dates
财产:
class User extends Model
{
use \Winter\Storm\Database\Traits\SoftDelete;
protected $dates = ['deleted_at'];
}
添加一个deleted_at
列到你的表,你可以使用softDeletes
来自迁移的方法:
Schema::table('posts', function ($table) {
$table->softDeletes();
});
现在,当你打电话给delete
模型上的方法,deleted_at
列将设置为当前时间戳。当查询使用软删除的模型时,“删除”的模型将不会包含在查询结果中。
要确定给定的模型实例是否已被软删除,请使用trashed
方法:
if ($user->trashed()) {
//
}
查询软删除模型
包括软删除模型
如上所述,软删除模型将自动从查询结果中排除。但是,您可以强制软删除模型出现在结果集中,使用withTrashed
查询方法:
$users = User::withTrashed()->where('account_id', 1)->get();
这withTrashed
方法也可以用在relationship 询问:
$flight->history()->withTrashed()->get();
仅检索软删除模型
这onlyTrashed
方法将检索only 软删除模型:
$users = User::onlyTrashed()->where('account_id', 1)->get();
恢复软删除模型
有时您可能希望“取消删除”软删除模型。要将软删除模型恢复到活动状态,请使用restore
模型实例上的方法:
$user->restore();
您也可以使用restore
查询中快速恢复多个模型的方法:
// Restore a single model instance...
User::withTrashed()->where('account_id', 1)->restore();
// Restore all related models...
$user->posts()->restore();
永久删除模型
有时您可能需要真正从数据库中删除模型。要从数据库中永久删除软删除模型,请使用forceDelete
方法:
// Force deleting a single model instance...
$user->forceDelete();
// Force deleting all related models...
$user->posts()->forceDelete();
软删除关系
当两个相关模型启用软删除时,您可以通过定义softDelete
中的选项关系定义.在此示例中,如果用户模型被软删除,则属于该用户的评论也将被软删除。
class User extends Model
{
use \Winter\Storm\Database\Traits\SoftDelete;
public $hasMany = [
'comments' => ['Acme\Blog\Models\Comment', 'softDelete' => true]
];
}
NOTE: 如果相关模型不使用软删除特性,它将被视为与
delete
选项并永久删除。
在这些相同的条件下,当恢复主要模型时,使用该模型的所有相关模型softDelete
选项也将恢复。
// Restore the user and comments
$user->restore();
具有 Sluggable 特征的软删除
默认情况下,Sluggable trait 会在生成 slug 时忽略软删除模型。 为了让模型修复不那么痛苦查看 Sluggable 部分.
Nullable
可空属性设置为NULL
当留空时。要取消模型中的属性,请应用Winter\Storm\Database\Traits\Nullable
特征并声明一个$nullable
属性与包含要取消的属性的数组。
class Product extends Model
{
use \Winter\Storm\Database\Traits\Nullable;
/**
* @var array Nullable attributes.
*/
protected $nullable = ['sku'];
}
HasSortableRelations
将此特征添加到您的模型中,以便对其关系进行排序/重新排序。
class MyModel extends model
{
use \Winter\Storm\Database\Traits\HasSortableRelations;
/**
* @var array Relations that can be sorted/reordered and the column name to use for sorting/reordering.
*/
public $sortableRelations = ['relation_name' => 'sort_order_column'];
...
}