模型特性用于实现通用功能。
可为空的属性在留空时会被设置为 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 属性, 其中包含一个带有要加密属性的数组.
class User extends Model
{
use \October\Rain\Database\Traits\Encryptable;
protected $encryptable = ['api_key', 'api_secret'];
}加密属性与 可 JSON 化属性 不兼容。
Slugs 是有意义的代码,常用于页面 URL 中。为了为您的模型自动生成一个唯一的 Slug,请应用 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 属性:
$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 trait 并确保你的 schema 定义了一个供其使用的列。
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 trait。
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 trait。此模型天然具备 SimpleTree trait 的所有功能。
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 模型使用内置的 验证器类。验证规则在模型类中定义为一个名为 $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 验证规则支持 创建 和 更新 修饰符,以便仅在模型分别被创建或更新时应用。以下内容仅在模型尚不存在时才需要。
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]
];
}如果相关模型不使用软删除特性,它将被视为与
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 |
|---|
all、group、locale。默认值:grouptrueprotected $propagatableSync = [
'sync' => 'all',
'delete' => false,
'except' => [
'description'
]
];使用多站点特性保存的模型默认情况下不会传播。使用 savePropagate 方法以确保传播规则生效。
$model->savePropagate();October CMS 模型可以通过存储修订来记录值的更改历史。要为模型存储修订,请应用 October\Rain\Database\Traits\Revisionable trait 并声明一个 $revisionable 属性,其中包含一个数组,该数组包含要监视更改的属性。您还需要定义一个名为 revision_history 的 $morphMany 模型关系,该关系引用名为 revisionable 的 System\Models\Revision 类,修订历史数据就存储在此处。
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;
}