laravelbook/ardent

此包已被废弃,不再维护。没有建议的替代包。

Laravel 5 的 Eloquent ORM 的自验证智能模型

3.6.0 2018-10-09 02:57 UTC

README

Latest Stable Version License Total Downloads Monthly Downloads Daily Downloads

Laravel 框架 5 的 Eloquent ORM 的自验证智能模型。

基于 Colby Rabideau 的 Laravel 3 的 Aware 包。

版权 (C) 2013-2015 Max Ehsan & Igor Santos

更新日志

访问我们的 发布列表。更新日志在那里制作:)

安装

laravelbook/ardent 添加到 composer.json 中的依赖项(在徽章上查看我们最新的稳定版本!)

{
    "require": {
        "laravelbook/ardent": "3.*"
    }
}

使用 composer update 更新您的包或使用 composer install 安装。

您还可以使用 composer require laravelbook/ardent 添加包,并稍后指定您想要的版本(目前,dev-master 是您的最佳选择)。

Laravel 之外的使用(自 1.1

如果您想将 Ardent 作为独立 ORM 包使用,请在项目的启动文件中使用以下配置(根据您的数据库更改属性)

\LaravelArdent\Ardent\Ardent::configureAsExternal(array(
  'driver'    => 'mysql',
  'host'      => 'localhost',
  'port'      => 3306,
  'database'  => 'my_system',
  'username'  => 'myself',
  'password'  => 'h4ckr',
  'charset'   => 'utf8',
  'collation' => 'utf8_unicode_ci'
), 'en'); //English is the default messages language, may be left empty

文档

简介

您在构建的应用程序中,是否经常发现自己重复创建相同的样板代码?这个典型的表单处理代码是否看起来太熟悉了?

Route::post('register', function() {
        $rules = array(
            'name'                  => 'required|between:3,80|alpha_dash',
            'email'                 => 'required|between:5,64|email|unique:users',
            'password'              => 'required|min:6|confirmed',
            'password_confirmation' => 'required|min:6'
        );

        $validator = Validator::make(Input::all(), $rules);

        if ($validator->passes()) {
            User::create(array(
                    'name'     => Input::get('name'),
                    'email'    => Input::get('email'),
                    'password' => Hash::make(Input::get('password'))
                ));

            return Redirect::to('/')->with('message', 'Thanks for registering!');
        } else {
            return Redirect::to('/')->withErrors($validator->getMessages());
        }
    }
);

自己实现这通常会导致大量的重复样板代码。作为额外的奖励,您的控制器(或路由处理器)会提前变得臃肿,并且代码变得混乱、丑陋且难以理解。

如果有人为您做了所有繁重的工作会怎样?如果,而不是重复上述混乱,您只需要键入这些几行代码呢?...

Route::post('register', function() {
        $user = new User;
        if ($user->save()) {
            return Redirect::to('/')->with('message', 'Thanks for registering!');
        } else {
            return Redirect::to('/')->withErrors($user->errors());
        }
    }
);

欢迎来到 Ardent!

Ardent - 由魔法粉尘驱动的,腕部友好的,一站式解决方案,解决您所有枯燥的输入清理样板代码!

开个玩笑,输入验证功能可以快速变得令人厌倦编写和维护。Ardent 通过提供自动化许多重复任务的助手来处理这些复杂性。

Ardent 不仅非常适合输入验证,它还将帮助您显着减少 Eloquent 数据模型代码。如果您发现自己多次在多个独立应用程序中编写非常相似的字节码,Ardent 尤其有用。

例如,用户注册或博客帖子提交是常见的编码需求,您可能希望在应用程序中实现并再次在其他应用程序中重用。使用 Ardent,您可以一次编写您的自我感知、智能模型,然后在其他项目中重用它们(无需或仅需少量修改)。一旦习惯了这种方式,您会真心想知道在没有 Ardent 的情况下您是如何应对的。

不再有重复的脑力劳动伤害了!

入门

Ardent旨在扩展Eloquent基类,而不改变其核心功能。由于Ardent自身是Illuminate\Database\Eloquent\Model的后代,因此所有您的Ardent模型都与Eloquent完全兼容,并可以利用 Laravel 强大的 OR/M 的全部功能。

要创建一个新的 Ardent 模型,只需让您的模型类继承自Ardent基类。在下面的示例中,我们将使用完整命名空间类来使示例更简洁,但您鼓励在所有类中使用use

use LaravelArdent\Ardent\Ardent;

class User extends Ardent {}

注意:您可以自由地将纯 Eloquent 模型与 Ardent 后代混合使用。如果一个模型对象不依赖于用户提交的内容,因此不需要验证,您可以将 Eloquent 模型类保持原样。

Ardent 中的轻松验证

Ardent 模型使用 Laravel 内置的Validator 类。为模型定义验证规则很简单,通常在您的模型类中作为静态变量完成。

class User extends \LaravelArdent\Ardent\Ardent {
  public static $rules = array(
    'name'                  => 'required|between:3,80|alpha_dash',
    'email'                 => 'required|between:5,64|email|unique:users',
    'password'              => 'required|min:6|confirmed',
    'password_confirmation' => 'required|min:6',
  );
}

注意:您还可以使用数组语法为验证规则。我希望您不介意旧 Laravel 文档链接,但尽管 Laravel 文档很好,不幸的是,5.1 之后就没有关于管道/数组语法的清晰参考了。

Ardent 模型在调用Ardent->save()时自动验证自己。

$user           = new User;
$user->name     = 'John doe';
$user->email    = 'john@doe.com';
$user->password = 'test';

$success = $user->save(); // returns false if model is invalid

注意:您还可以使用Ardent->validate()方法在任何时候验证模型。

检索验证错误

当一个 Ardent 模型验证失败时,一个包含验证失败信息的Illuminate\Support\MessageBag对象附加到 Ardent 对象上。

使用Ardent->errors()方法或Ardent->validationErrors属性检索验证错误信息集合实例。

使用Ardent->errors()->all()检索所有验证错误。使用Ardent->validationErrors->get('attribute')检索特定属性的错误。

注意:Ar dent 利用 Laravel 的 MessagesBag 对象,它有一个简单且优雅的格式化错误的方法

覆盖验证

有两种方法可以覆盖 Ardent 的验证

1. 强制保存

forceSave()验证模型,但保存,无论是否有验证错误。

2. 覆盖规则和消息

两者的Ardent->save($rules, $customMessages)Ardent->validate($rules, $customMessages)都接受两个参数

  • $rules是一个与Ardent::$rules相同的格式的验证器规则数组。
  • 同样,也适用于$customMessages参数(与Ardent::$customMessages相同)

一个非空的数组将仅覆盖该实例的类中指定的规则或自定义错误消息。

注意:默认情况下,$rules$customMessages的值是空的array();因此,如果您传递一个array(),则不会覆盖任何内容。

自定义验证错误消息

就像Laravel验证器一样,Ardent允许您使用相同的语法来设置自定义错误消息。

class User extends \LaravelArdent\Ardent\Ardent {
  public static $customMessages = array(
    'required' => 'The :attribute field is required.',
    ...
  );
}

自定义验证规则

您可以像为Laravel验证器创建自定义验证规则一样创建自定义验证规则。

模型钩子(自2.0版起)

Ardent在Eloquent模型事件上提供了一些语法糖:传统的模型钩子。它们是连接到模型生命周期不同时刻的附加操作的简单方法。它们可以在删除条目之前进行额外的清理工作,在验证发生之后进行自动修复或更新更新发生的关联模型。

所有返回false(特别是布尔值,而不是简单的“假”值)的before钩子将停止操作。所以,例如,如果您想在beforeSave方法中发生错误时停止保存,只需返回false即可,保存将不会发生,并且显然也不会调用afterSave

以下是所有可用的钩子列表

  • before/afterCreate()
  • before/afterSave()
  • before/afterUpdate()
  • before/afterDelete()
  • before/afterValidate() - 当返回false时将停止验证,因此save()操作将失败,因为验证失败了。

例如,您可以使用beforeSave来哈希用户的密码(实际上,使用自动哈希会更好!)

class User extends \LaravelArdent\Ardent\Ardent {
  public function beforeSave() {
    // if there's a new password, hash it
    if($this->isDirty('password')) {
      $this->password = Hash::make($this->password);
    }
    
    return true;
    //or don't return nothing, since only a boolean false will halt the operation
  }
}

额外的beforeSave和afterSave(自1.0版起)

beforeSaveafterSave可以在运行时包含在内。只需将闭包作为参数传递给save()(或forceSave())方法即可。

$user->save(array(), array(), array(),
  function ($model) { // closure for beforeSave
    echo "saving the model object...";
    return true;
  },
  function ($model) { // closure for afterSave
    echo "done!";
  }
);

注意:闭包应该有一个参数,因为它会传递一个指向正在保存的模型的引用。

更简洁的关系定义(自2.0版起)

您是否曾经编写了一个带有许多关系的Eloquent模型,只是注意到您的类有多乱,所有这些几乎与方法名本身内容相同的单行代码?

在Ardent中,您可以在一个数组中干净地定义您的关联及其信息,并且它们将像您在方法中定义它们一样工作。以下是一个示例

class User extends \LaravelArdent\Ardent\Ardent {
  public static $relationsData = array(
    'address' => array(self::HAS_ONE, 'Address'),
    'orders'  => array(self::HAS_MANY, 'Order'),
    'groups'  => array(self::BELONGS_TO_MANY, 'Group', 'table' => 'groups_have_users')
  );
}

$user = User::find($id);
echo "{$user->address->street}, {$user->address->city} - {$user->address->state}";

数组语法如下

  • 第一个索引值:关系名称,可以是以下之一:hasOnehasManybelongsTobelongsToManymorphTomorphOnemorphMany,或者相关的常量(例如 Ardent::HAS_MANYArdent::MORPH_ONE)。
  • 第二个索引值:类名,包含完整的命名空间。例外是 morphTo 关系,它不取任何额外的参数。
  • 命名参数,遵循原始 Eloquent 方法中定义的参数
    • foreignKey [可选],对 hasOnehasManybelongsTobelongsToMany 有效
    • tableotherKey [可选]、timestamps [布尔值,可选] 和 pivotKeys [数组,可选],对 belongsToMany 有效
    • nametypeid,由 morphTomorphOnemorphMany 使用(后两者需要定义 name

注意:这个功能是基于简单的 Yii 1.1 ActiveRecord 的关系

自动填充 Ardent 实体

Ardent 能够自动从表单输入提交中填充你的实体模型类!

让我们看看它是如何工作的。考虑以下代码片段

$user           = new User;
$user->name     = Input::get('name');
$user->email    = Input::get('email');
$user->password = Hash::make(Input::get('password'));
$user->save();

让我们施展 Ardent 的 魔力 并重写前面的代码片段

$user = new User;
$user->save();

就是这样!我们只是移除了无聊的部分。

信不信由你,上面的代码实际上执行的任务与它的旧版本(虽然相当冗长)几乎相同。Ardent 使用用户提交的表单数据填充模型对象的属性。不再需要费尽心思去找出你忘记填充的哪个 Eloquent 属性。让 Ardent 处理无聊的事情,而你则专注于有趣的事情!
它遵循相同的 批量赋值规则,这取决于 $fillable/$guarded 属性。

要启用自动填充功能,只需在模型类中将 $autoHydrateEntityFromInput 实例变量设置为 true。然而,为了防止填充已存在的属性,如果你想在更新场景中也启用自动填充,你应该使用 $forceEntityHydrationFromInput

class User extends \LaravelArdent\Ardent\Ardent {
  public $autoHydrateEntityFromInput = true;    // hydrates on new entries' validation
  public $forceEntityHydrationFromInput = true; // hydrates whenever validation is called
}

自动清除冗余表单数据

Ardent 模型可以 自动地 清除冗余输入数据(例如 密码确认、隐藏的 CSRF _token 或自定义 HTTP _method 字段)——这样额外的数据就永远不会保存到数据库中。Ardent 将使用确认字段来验证表单输入,然后谨慎地丢弃这些属性,在将模型实例保存到数据库之前!

要启用此功能,只需在模型类中将 $autoPurgeRedundantAttributes 实例变量设置为 true

class User extends \LaravelArdent\Ardent\Ardent {
  public $autoPurgeRedundantAttributes = true;
}

您还可以清除其他字段。属性 Ardent::$purgeFilters 是一个数组,您可以向其中添加自定义规则。这些闭包接收属性键作为参数,并应该返回 false 以清除属性。例如

function __construct($attributes = array()) {
  parent::__construct($attributes);

  $this->purgeFilters[] = function($key) {
    $purge = array('tempData', 'myAttribute');
    return ! in_array($key, $purge);
  };
}

自动转换安全文本属性

假设在你的模型类中有一个名为 password 的属性,但你不想在数据库中存储明文版本。最实际的办法是存储原始内容的哈希值。别担心,Ardent 完全能自动为你转换任意数量的安全字段!

要实现这一点,请将属性名称添加到你的模型类中的静态数组变量 Ardent::$passwordAttributes 中,并将实例变量 $autoHashPasswordAttributes 设置为 true

class User extends \LaravelArdent\Ardent\Ardent {
  public static $passwordAttributes  = array('password');
  public $autoHashPasswordAttributes = true;
}

Ardent 会自动将明文密码属性替换为安全的哈希校验和并保存到数据库。它内部使用 Laravel 的 Hash::make() 方法来生成哈希。 注意:建议使用 Eloquent 的 $hidden 属性,这样即使密码被哈希,如果构建 API 或类似的东西,也不会轻易显示出来 :)

如果你使用的是独立的 Ardent,可以使用 Ardent::$hasher 来验证字段值,例如使用 User::$hasher->check($given_password, $user->password).

具有唯一规则的更新

Ardent 可以帮助你处理具有唯一规则的更新。根据 Laravel 文档,当你更新(因此验证)具有唯一规则的字段时,你必须传入你要更新的记录的唯一 ID。如果没有传入此 ID,验证将会失败,因为 Laravel 的验证器会认为这是一条重复记录。

来自 Laravel 文档

    'email' => 'unique:users,email,10'

以前,程序员必须手动管理在运行时传递 ID 和更改规则集以包含 ID 的操作。但是,与 Ardent 不同。只需设置你的规则为 unique,调用函数 updateUniques,Ardent 就会处理其余部分。

示例

在你的扩展模型中定义你的规则

  public static $rules = array(
     'email' => 'required|email|unique',
     'password' => 'required|between:4,20|confirmed',
     'password_confirmation' => 'between:4,20',
  );

在你的控制器中,当你需要更新时,只需调用

$model->updateUniques();

如果需要,你可以将规则在运行时传递给 updateUniques,否则它将使用你的模型提供的静态规则。

注意,在上面的规则示例中,我们没有告诉验证器使用哪个表或哪个字段,正如 Laravel 文档中所描述的(例如 unique:users,email,10)。Ardent 足够聪明,可以自己解决这个问题。(感谢 github 用户 @Sylph)