模型特性用于实现通用功能。
可空属性在留空时会被设为 NULL。要在模型中将属性设为 NULL,请应用 October\Rain\Database\Traits\Nullable trait,并声明一个 $nullable 属性,该属性是一个包含要设为 NULL 的属性的数组。
class Product extends Model
{
use \October\Rain\Database\Traits\Nullable;
protected $nullable = ['sku'];
}散列属性在首次在模型上设置时会立即进行哈希处理。要在模型中对属性进行哈希处理,请应用 October\Rain\Database\Traits\Hashable trait,并声明一个 $hashable 属性,该属性是一个包含要进行哈希处理的属性的数组。
class User extends Model
{
use \October\Rain\Database\Traits\Hashable;
protected $hashable = ['password'];
}净化属性在模型创建或更新时将不会保存到数据库。要在模型中净化属性,应用 October\Rain\Database\Traits\Purgeable trait 并声明一个 $purgeable 属性,其中包含一个待净化属性的数组。
class User extends Model
{
use \October\Rain\Database\Traits\Purgeable;
protected $purgeable = ['password_confirmation'];
}使用 getOriginalPurgeValue 查找在模型保存后被清除的值。
return $user->getOriginalPurgeValue('password_confirmation');或者,使用 restorePurgedValues 方法来恢复所有已清除的值。
$user->restorePurgedValues();类似于 Hashable trait,加密属性在设置时会被加密,但在检索时也会被解密。要在模型中加密属性,请应用 October\Rain\Database\Traits\Encryptable trait,并声明一个 $encryptable property,其中包含要加密的属性。
class User extends Model
{
use \October\Rain\Database\Traits\Encryptable;
protected $encryptable = ['api_key', 'api_secret'];
}加密属性不兼容可 JSON 化的属性.
Slugs 是常用于页面 URL 的有意义代码。要为你的模型自动生成唯一的段码,请应用 October\Rain\Database\Traits\Sluggable Trait 并声明一个 $slugs 属性。
class User extends Model
{
use \October\Rain\Database\Traits\Sluggable;
protected $slugs = ['slug' => 'name'];
}$slugs 属性应该是一个数组,其中键是 slug 的目标列,且值是用于生成 slug 的源字符串。在上述示例中,如果 name 列被设置为 Cheyenne,结果是 slug 列将被设置为 cheyenne,cheyenne-2,或 cheyenne-3,等,在模型创建之前。
要从多个来源生成 slug,请将另一个数组作为源值传递:
protected $slugs = [
'slug' => ['first_name', '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();已排序的模型将在 sort_order 中存储一个数值,用于维护集合中每个独立模型的排序顺序。要将 sort_order 列添加到您的表中,您可以在迁移文件中使用 integer 方法。
Schema::table('users', function ($table) {
$table->integer('sort_order')->default(0);
});为了存储模型的排序顺序,请应用 October\Rain\Database\Traits\Sortable 特性,并确保您的模式定义了一个供其使用的列。
class User extends Model
{
use \October\Rain\Database\Traits\Sortable;
}你可以通过定义 SORT_ORDER 常量来修改用于标识排序顺序的键名。
const SORT_ORDER = 'my_sort_order_column';使用 setSortableOrder 方法来设置多个记录的排序。该数组包含模型标识符,并按照它们应该出现的排序。
$user->setSortableOrder([3, 2, 1]);如果对记录子集进行排序,第二个数组用于提供排序值参考池。例如,以下将排序顺序列赋值为 100、200 或 300。
$user->setSortableOrder([3, 2, 1], [100, 200, 300]);简单的树形模型将使用 parent_id 列维护模型间的父子关系。要将 parent_id 列添加到你的表中,你可以在迁移中使用 integer 方法。
Schema::table('categories', function ($table) {
$table->integer('parent_id')->nullable()->unsigned();
});要使用简单树,应用October\Rain\Database\Traits\SimpleTree特性.
class Category extends Model
{
use \October\Rain\Database\Traits\SimpleTree;
}此 trait 将自动注入两个 模型关系,名为 parent 和 children,这等同于以下定义。
public $belongsTo = [
'parent' => [Category ::class, 'key' => 'parent_id'],
];
public $hasMany = [
'children' => [Category ::class, 'key' => 'parent_id'],
];你不需要自己定义这些关系,然而,你可以通过定义 PARENT_ID 常量来修改用于识别父级的键名:
const PARENT_ID = 'my_parent_column';使用此 trait 的模型集合将返回 October\Rain\Database\TreeCollection 类型,该类型添加了 toNested 方法。为了构建一个预加载的树形结构,返回关系已预加载的记录。
Category::all()->toNested();为了渲染所有层级的项及其子项, 你可以使用递归处理
{% macro renderChildren(item) %}
{% 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 nav %}
{{ nav.renderChildren(category)|raw }}该 嵌套集合模型 是一种先进技术,用于使用 parent_id、nest_left、nest_right 和 nest_depth 列维护模型之间的层级结构。要将这些列添加到您的表中, 您可以在迁移中使用这些方法。
Schema::table('categories', function ($table) {
$table->integer('parent_id')->nullable()->unsigned();
$table->integer('nest_left')->nullable();
$table->integer('nest_right')->nullable();
$table->integer('nest_depth')->nullable();
});要使用嵌套集模型,应用 October\Rain\Database\Traits\NestedTree 特性。SimpleTree 特性的所有功能在此模型中都是固有的。
class Category extends Model
{
use \October\Rain\Database\Traits\NestedTree;
}默认情况下,所有节点都创建为根:
$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(): 使当前节点成为根节点。October CMS 模型使用内置的 Validator 类. 验证规则在模型类中定义作为属性名为 $rules 并且该类必须使用 trait October\Rain\Database\Traits\Validation.
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']
];
}您也可以使用 数组语法 用于验证规则。
public $rules = [
'links.*.url' => ['required', 'url'],
'links.*.anchor' => ['required']
];模型在 save 方法被调用时会自动验证自身。
$user = new User;
$user->name = 'Actual Person';
$user->email = 'a.person@example.tld';
$user->password = 'passw0rd';
// Returns false if model is invalid
$success = $user->save();你也可以在任何时候使用
validate方法验证模型。
unique 验证规则会自动配置,并且不需要指定表名。
public $rules = [
'name' => ['unique'],
];该 required 验证规则支持 create 和 update 修饰符,分别仅在模型创建或更新时应用。 以下内容仅在模型尚不存在时才需要。
public $rules = [
'password' => ['required:create'],
];当模型验证失败时,一个 Illuminate\Support\MessageBag 对象会附加到模型上。该对象包含验证失败消息。使用 errors 方法或 $validationErrors 属性可以检索验证错误消息集合实例。使用 errors()->all() 可以检索所有验证错误。使用 validationErrors->get('attribute') 可以检索 特定属性的错误。
模型利用
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 \October\Rain\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 时间戳会被设置在该记录上。要为模型启用软删除,请将 October\Rain\Database\Traits\SoftDelete trait 应用到该模型,并将 deleted_at 列添加到你的 $dates 属性中:
class User extends Model
{
use \October\Rain\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 方法也可以用于查询一个 关系:
$flight->history()->withTrashed()->get();该 onlyTrashed 方法将仅检索软删除的模型:
$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 \October\Rain\Database\Traits\SoftDelete;
public $hasMany = [
'comments' => [\Acme\Blog\Models\Comment::class, 'softDelete' => true]
];
}如果相关模型未使用软删除 trait,它将被视为与
delete选项相同,并永久删除。
在这些相同条件下,当主模型被恢复时,所有使用了 softDelete 选项的相关模型也将被恢复。
// Restore the user and comments
$user->restore();软删除记录不作为关联查询的一部分,但是,您可以通过向查询添加 withTrashed 作用域来包含它们。
class User extends Model
{
public $hasMany = [
'comments' => [\Acme\Blog\Models\Comment::class, 'scope' => 'withTrashed']
];
}当将多站点应用于模型时,只有属于活跃站点的记录才可供管理。活跃站点与记录上设置的 site_id 列关联。要为一个模型启用多站点,请应用 October\Rain\Database\Traits\Multisite Trait,并使用 $propagatable 属性定义要在所有记录之间传播的属性:
class User extends Model
{
use \October\Rain\Database\Traits\Multisite;
protected $propagatable = ['api_code'];
}该
$propagatable是多站点 trait 所必需的,但可以留空为一个空数组,以禁用任何属性的传播。
要为您的表添加一个 site_id 列,您可以使用迁移中的 integer 方法。也可以使用 site_root_id 通过根记录将多条记录关联起来。
Schema::table('posts', function ($table) {
$table->integer('site_id')->nullable()->index();
$table->integer('site_root_id')->nullable()->index();
});现在,当记录创建时,它将被分配到活动站点,并且切换到不同的站点将自动传播一个新记录。更新记录时,传播的字段会被复制到属于根记录的每个记录中。
在某些情况下,所有记录都必须存在于每个站点,例如分类和标签。您可以通过将 $propagatableSync 属性设置为 true 来强制每个记录在所有站点中都存在,该属性默认为 false。启用后,在模型保存后,它将为其他站点创建相同的模型,如果它们尚不存在。
protected $propagatableSync = true;当使用 站点组 时,记录将传播到该组内的所有站点。这可以通过将 $propagatableSync 属性设置为包含配置选项的数组来控制。
| Option | Description |
|---|
所有、组、区域设置。默认值:组trueprotected $propagatableSync = [
'sync' => 'all',
'delete' => false,
'except' => [
'description'
]
];使用多站点特性保存的模型默认情况下不会传播。使用 savePropagate 方法以确保传播规则生效。
$model->savePropagate();October CMS 模型可以通过存储修订记录值的更改历史。要为模型存储修订,请应用 October\Rain\Database\Traits\Revisionable trait 并声明一个 $revisionable 属性,其中包含一个数组,该数组包含要监视更改的属性。您还需要定义一个名为 revision_history 的 $morphMany 模型关系,该关系引用 System\Models\Revision 类,名称为 revisionable,修订历史数据就存储在此处。
class User extends Model
{
use \October\Rain\Database\Traits\Revisionable;
protected $revisionable = ['name', 'email'];
public $morphMany = [
'revision_history' => [\System\Models\Revision::class, 'name' => 'revisionable']
];
}默认情况下,最多将保留 500 条记录,但是,这可以通过在模型上声明一个 $revisionableLimit 属性并设置新的限制值来修改。
/**
* @var int revisionableLimit as the maximum number 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;
}