Database Traits
- Hashable
- Purgeable
- Encryptable
- Sluggable
- Revisionable
- Sortable
- Simple Tree
- Nested Tree
- Validation
- Soft deleting
- Nullable
model traits 用于实现通用功能。
Hashable 哈希
首次在模型上设置属性时,会立即对哈希属性进行哈希处理。
要对模型中的属性进行哈希处理,请应用October\Rain\Database\Traits\Hashable
特征
并声明一个带有包含要哈希的属性的数组的$hashable
属性。
class User extends Model
{use \October\Rain\Database\Traits\Hashable;/*** 创建一个哈希数组属性列表*/protected $hashable = ['password'];
}
Purgeable
创建或更新模型时,清除的属性不会保存到数据库中。
为了在你的model中清除,用October\Rain\Database\Traits\Purgeable
trait
声明一个$purgeable
属性,该数组包含要清除的属性
class User extends Model
{use \October\Rain\Database\Traits\Purgeable;/*** @var array List of attributes to purge.*/protected $purgeable = ['password_confirmation'];
}
保存模型时,定义的属性将在触发[模型事件](#model-events)(包括验证)之前清除。
使用 getOriginalPurgeValue
查找已清除的值。
return $user->getOriginalPurgeValue('password_confirmation');
Encryptable 可加密
Similar to the hashable trait, encrypted attributes are encrypted when set but also decrypted when an attribute is retrieved. To encrypt attributes in your model, apply the October\Rain\Database\Traits\Encryptable
trait and declare a $encryptable
property with an array containing the attributes to encrypt.
class User extends Model
{use \October\Rain\Database\Traits\Encryptable;/*** @var array List of attributes to encrypt.*/protected $encryptable = ['api_key', 'api_secret'];
}
Note: Encrypted attributes will be serialized and unserialized as a part of the encryption / decryption process. Do not make an attribute that is
encryptable
alsojsonable
at the same time as thejsonable
process will attempt to decode a value that has already been unserialized by the encryptor.
Sluggable
Slugs are meaningful codes that are commonly used in page URLs. To automatically generate a unique slug for your model, apply the October\Rain\Database\Traits\Sluggable
trait and declare a $slugs
property.
class User extends Model
{use \October\Rain\Database\Traits\Sluggable;/*** @var array Generate slugs for these attributes.*/protected $slugs = ['slug' => 'name'];
}
The $slugs
property should be an array where the key is the destination column for the slug and the value is the source string used to generate the slug. In the above example, if the name
column was set to Cheyenne, as a result the slug
column would be set to cheyenne, cheyenne-2, or cheyenne-3, etc before the model is created.
To generate a slug from multiple sources, pass another array as the source value:
protected $slugs = ['slug' => ['first_name', 'last_name']
];
Slugs are only generated when a model first created. To override or disable this functionality, simply set the slug attribute manually:
$user = new User;
$user->name = 'Remy';
$user->slug = 'custom-slug';
$user->save(); // Slug will not be generated
Use the slugAttributes
method to regenerate slugs when updating a model:
$user = User::find(1);
$user->slug = null;
$user->slugAttributes();
$user->save();
Sluggable with SoftDelete trait
By default, soft deleted models are ignored when the slug is generated.
You might want to prevent slug duplication when recovering soft deleted models.
Set the $allowTrashedSlugs
attribute to true
in order to take into account soft deleted records when generating new slugs.
protected $allowTrashedSlugs = true;
Revisionable
October models can record the history of changes in values by storing revisions. To store revisions for your model, apply the October\Rain\Database\Traits\Revisionable
trait and declare a $revisionable
property with an array containing the attributes to monitor for changes. You also need to define a $morphMany
model relation called revision_history
that refers to the System\Models\Revision
class with the name revisionable
, this is where the revision history data is stored.
class User extends Model
{use \October\Rain\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']];
}
By default 500 records will be kept, however this can be modified by declaring a $revisionableLimit
property on the model with a new limit value.
/*** @var int Maximum number of revision records to keep.*/
public $revisionableLimit = 8;
The revision history can be accessed like any other relation:
$history = User::find(1)->revision_history;foreach ($history as $record) {echo $record->field . ' updated ';echo 'from ' . $record->old_value;echo 'to ' . $record->new_value;
}
The revision record optionally supports a user relationship using the user_id
attribute. You may include a getRevisionableUser
method in your model to keep track of the user that made the modification.
public function getRevisionableUser()
{return BackendAuth::getUser()->id;
}
Sortable
Sorted models will store a number value in sort_order
which maintains the sort order of each individual model in a collection. To store a sort order for your models, apply the October\Rain\Database\Traits\Sortable
trait and ensure that your schema has a column defined for it to use (example: $table->integer('sort_order')->default(0);
).
class User extends Model
{use \October\Rain\Database\Traits\Sortable;
}
You may modify the key name used to identify the sort order by defining the SORT_ORDER
constant:
const SORT_ORDER = 'my_sort_order_column';
Use the setSortableOrder
method to set the orders on a single record or multiple records.
// 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: If adding this trait to a model where data (rows) already existed previously, the data set may need to be initialized before this trait will work correctly. To do so, either manually update each row’s
sort_order
column or run a query against the data to copy the record’sid
column to thesort_order
column (ex.UPDATE myvendor_myplugin_mymodelrecords SET sort_order = id
).
Simple Tree
一个简单的树模型
使用parent_id
列维护模型之间的父子关系。
class Category extends Model
{use \October\Rain\Database\Traits\SimpleTree;
}
此特征将自动注入两个名为 parent
和 children
的model relations模型关系 ,它等效于以下定义:
public $belongsTo = ['parent' => ['User', 'key' => 'parent_id'],
];public $hasMany = ['children' => ['User', 'key' => 'parent_id'],
];
您可以通过定义PARENT_ID
常量来修改用于标识父项的键名:
const PARENT_ID = 'my_parent_column';
使用此特征的模型集合将返回October\Rain\Database\TreeCollection
的类型,该类型添加了toNested
方法。
要构建一个预先加载的树结构,请返回具有预先加载的关系的记录。
Category::all()->toNested();
Rendering
In order to render all levels of items and their children, you can use recursive processing
{% 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 }}
Nested Tree 嵌套树
嵌套集模型nested set model 是一种高级技术,可使用parent_id
, nest_left
, nest_right
, 和 nest_depth
列维护模型之间的层次结构。
要使用嵌套集合模型,请应用October \ Rain \ Database \ Traits \ NestedTree
特性。此模型固有地具有SimpleTree
特性的所有功能。
class Category extends Model
{use \October\Rain\Database\Traits\NestedTree;
}
Creating a root node 创建根节点
缺省下,被创建的节点都是根节点
$root = Category::create(['name' => 'Root category']);
另外 你可能想把现有节点转为根节点
$node->makeRoot();
您也可以使它的 parent_id
列无效,其作用与`makeRoot’.一样。
$node->parent_id = null;
$node->save();
Inserting nodes 插入节点
您可以通过relation直接插入新节点:
$child1 = $root->children()->create(['name' => 'Child 1']);
或对现有节点使用makeChildOf
方法:
$child2 = Category::create(['name' => 'Child 2']);
$child2->makeChildOf($root);
Deleting nodes 删除节点
当使用delete
方法删除一个节点时,该节点的所有后代也将被删除。请注意,不会为子模型触发delete事件 model events
$child1->delete();
Getting the nesting level of a node 获取节点的嵌套级别
用getLevel
方法返回当前节点嵌套级别或深度
// 0 when root
$node->getLevel()
Moving nodes around 移动节点
有几种移动节点的方法:
moveLeft()
: 找到左侧的兄弟并移到左侧。moveRight()
: 找到正确的兄弟并移到它的右边。moveBefore($otherNode)
: 移动节点到…的左侧moveAfter($otherNode)
: 移动节点到…的右侧makeChildOf($otherNode)
: 成为…的子节点makeRoot()
: 当前节点变成根节点
Validation 验证
使用内置的验证类 Validator class.
验证规则在模型类中定义为名为$ rules的属性。
必须使用October\Rain\Database\Traits\Validation
trait
class User extends Model
{use \October\Rain\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: 你也可以自由使用array 语法 来验证规则。
当调用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方法来验证模型。
Retrieving validation errors 检索验证错误
如果模型无法通过验证,则会将Illuminate\Support\MessageBag
对象附加到模型。
该对象包含验证失败消息。使用errors
方法或$ validationErrors属性检索验证错误消息集合实例。
使用errors()->all()
检索所有验证错误。使用vvalidationErrors->get('attribute')
检索特定属性的错误。
Note: 该模型利用MessagesBag对象 参见 services/validation#working-with-error-messages
Overriding validation 跳过验证
forceSave
方法将验证模型并保存,无论是否存在验证错误。
$user = new User;//创建未经验证的用户
$user->forceSave();
Custom error messages 自定义错误信息
参见/services/validation#custom-error-messages
class User extends Model
{public $customMessages = ['required' => 'The :attribute field is required.',...];
}
Custom attribute names 自定义属性名
你也可以使用$attributeNames
数组设置自定义属性名称
class User extends Model
{public $attributeNames = ['email' => 'Email Address',...];
}
Dynamic validation rules 动态验证规则
您可以通过覆盖beforeValidate
model event 方法来动态应用规则。
在这里,我们检查is_remote
属性是否为false
,然后将latitude
和 longitude
属性动态设置为必填字段。
public function beforeValidate()
{if (!$this->is_remote) {$this->rules['latitude'] = 'required';$this->rules['longitude'] = 'required';}
}
Custom validation rules 自定义验证规则
参看 /services/validation#custom-validation-rules
Soft deleting
When soft deleting a model, it is not actually removed from your database. Instead, a deleted_at
timestamp is set on the record. To enable soft deletes for a model, apply the October\Rain\Database\Traits\SoftDelete
trait to the model and add the deleted_at column to your $dates
property:
class User extends Model
{use \October\Rain\Database\Traits\SoftDelete;protected $dates = ['deleted_at'];
}
To add a deleted_at
column to your table, you may use the softDeletes
method from a migration:
Schema::table('posts', function ($table) {$table->softDeletes();
});
Now, when you call the delete
method on the model, the deleted_at
column will be set to the current timestamp. When querying a model that uses soft deletes, the “deleted” models will not be included in query results.
To determine if a given model instance has been soft deleted, use the trashed
method:
if ($user->trashed()) {//
}
Querying soft deleted models
Including soft deleted models
As noted above, soft deleted models will automatically be excluded from query results. However, you may force soft deleted models to appear in a result set using the withTrashed
method on the query:
$users = User::withTrashed()->where('account_id', 1)->get();
The withTrashed
method may also be used on a relationship query:
$flight->history()->withTrashed()->get();
Retrieving only soft deleted models
The onlyTrashed
method will retrieve only soft deleted models:
$users = User::onlyTrashed()->where('account_id', 1)->get();
Restoring soft deleted models
Sometimes you may wish to “un-delete” a soft deleted model. To restore a soft deleted model into an active state, use the restore
method on a model instance:
$user->restore();
You may also use the restore
method in a query to quickly restore multiple models:
// Restore a single model instance...
User::withTrashed()->where('account_id', 1)->restore();// Restore all related models...
$user->posts()->restore();
Permanently deleting models
Sometimes you may need to truly remove a model from your database. To permanently remove a soft deleted model from the database, use the forceDelete
method:
// Force deleting a single model instance...
$user->forceDelete();// Force deleting all related models...
$user->posts()->forceDelete();
Soft deleting relations
When two related models have soft deletes enabled, you can cascade the delete event by defining the softDelete
option in the relation definition. In this example, if the user model is soft deleted, the comments belonging to that user will also be soft deleted.
class User extends Model
{use \October\Rain\Database\Traits\SoftDelete;public $hasMany = ['comments' => ['Acme\Blog\Models\Comment', 'softDelete' => true]];
}
Note: If the related model does not use the soft delete trait, it will be treated the same as the
delete
option and deleted permanently.
Under these same conditions, when the primary model is restored, all the related models that use the softDelete
option will also be restored.
// Restore the user and comments
$user->restore();
Soft Delete with Sluggable trait
By default, Sluggable trait will ignore soft deleted models when the slug is generated.
In order to make the model restoration less painful checkout the Sluggable section.
Nullable
Nullable attributes are set to NULL
when left empty. To nullify attributes in your model, apply the October\Rain\Database\Traits\Nullable
trait and declare a $nullable
property with an array containing the attributes to nullify.
class Product extends Model
{use \October\Rain\Database\Traits\Nullable;/*** @var array Nullable attributes.*/protected $nullable = ['sku'];
}