标签 Laravel 下的文章

trait class 的定义

namespace App\Library\Model;

use Illuminate\Contracts\Validation\Factory;

trait WithValidates
{

//    protected $rules = [];
//    protected $customMessages = [];
//    protected $customAttributes = [];

    /**
     * @param $validator
     *
     * @return array
     */
    public function validateWith($validator)
    {
        if (is_array($validator)) {
            $validator = $this->getValidator($this->attributes, $validator);
        }
        $validator->after(function ($validate) {
            return call_user_func('self::afterValidate', $validate);
        });
        return $validator->validate();
    }

    protected function getValidator($data, $rules = [], $messages = [], $customAttributes = [])
    {
        return $this->getValidationFactory()->make($data, $rules ?: [], $messages ?: [], $customAttributes ?: []);
    }

    /**
     * Get a validation factory instance.
     * @return Factory
     */
    protected function getValidationFactory()
    {
        return app(Factory::class);
    }

    /**
     * @param null $rules
     * @param null $messages
     * @param null $customAttributes
     *
     * @return array
     */
    public function validate($rules = [], $messages = [], $customAttributes = [])
    {
        $validator = $this->getValidator(
            $this->attributes,
            $rules ?: $this->rules,
            $messages ?: $this->customMessages,
            $customAttributes ?: $this->customAttributes
        );
        $validator->after(function ($validate) {
            return call_user_func('self::afterValidate', $validate);
        });
        return $validator->validate();
    }

    /**
     * @param $validator
     */
    protected function afterValidate($validator)
    {

    }

}

简单使用

namespace App;

use Illuminate\Database\Eloquent\Model;

class Tooltip extends Model
{
    use WithValidates;
    protected $rules = [
        'category' => 'string|required|max:64',
        'field' => 'string|required|max:64',
        'index' => 'integer|nullable',
        'description' => 'string|nullable',
    ];

    protected $fillable = [
        'category',
        'field',
        'index',
        'description',
    ];
}

abstract class 的方式来使用

abstract class BasicModel extends Model
{
    use WithValidates;

    protected $perPage = 10;
    protected $rules = [];
    protected $customMessages = [];
    protected $customAttributes = [];
}

model file usage

namespace App;

use App\Library\Model\BasicModel;

class Tooltip extends BasicModel
{
    protected $rules = [
        'category' => 'string|required|max:64',
        'field' => 'string|required|max:64',
        'index' => 'integer|nullable',
        'description' => 'string|nullable',
    ];

    protected $fillable = [
        'category',
        'field',
        'index',
        'description',
    ];
}

ResourceCollection 是用于处理 返回值为json的时候定义返回的集合的格式,集合内的单个元素可以使用 Illuminate\Http\Resources\Json\JsonResource 定义,或者直接在toArray中重新定义。

use App\User;
use App\Http\Resources\User as UserResource;

Route::get('/user', function () {
    return UserResource::collection(User::all());
});

// 如果定义了Collection 

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\ResourceCollection;

class UserCollection extends ResourceCollection
{
    /**
     * Transform the resource collection into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'data' => $this->collection,
            'links' => [
                'self' => 'link-value',
            ],
        ];
    }
}
// 新的写法
use App\User;
use App\Http\Resources\UserCollection;

Route::get('/users', function () {
    return new UserCollection(User::all());
});

当前使用版本 v1.6.3

belongsTo 关系使用问题

  • 外键名必须填写,否则不能正确的保存。
  • 外键需要允许为空(nullable)否则会报错(已经提交issue截止目前未修复)

    // tables 
          Schema::create('users', function (Blueprint $table) {
              $table->uuid('id');
              $table->string('email', 64)->unique();
              $table->boolean('revoked')->default(0);
              $table->dateTime('email_verified_at')->nullable();
              $table->string('password');
              $table->rememberToken();
              $table->timestamps();
          });
    
    
          Schema::create('profiles', function (Blueprint $table) {
              $table->increments('id');
              $table->uuid('user_id')->nullable()->index();  // 目前需要为 nullable, 这个bug目前为止还没有修复
              $table->string('name');
              $table->string('description')->nullable();
              $table->timestamps();
          });
    class Teacher extends Model
    {
      protected $guarded=[];
      //
      public function user() {
          return $this->belongsTo(User::class, 'user_id', 'id');  // 这里必须填写,虽然Laravel 虽然在Laravel 中默认就是这些值,但是Laravel-Admin 没办法获取到默认的字段名
      }
    }
    // Model
    
    class User extends Authenticatable
    {
      use Notifiable;
    
      public $incrementing=false;
      /**
       * The attributes that should be hidden for arrays.
       *
       * @var array
       */
      protected $hidden = [
          'password', 'remember_token',
      ];
    
      public function profile() {
          return $this->hasOne(Profile::class);
      }
    }
    
    // Form
    
          $form = new Form(new Profile);
    
          $form->text('name', '姓名')->rules('required');
          $form->password('user.email', '密码')->rules('required');
          $form->password('user.password', '密码')->rules('required');
          $form->textarea('description', '描述');
    
    //
    

    haseMany 关系

  • 主键必须为自动生成,否则不能正确的保存从表
    tables

    CREATE TABLE `main` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
    `name` varchar(255) NOT NULL,
    PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    CREATE TABLE `sub` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT, // 非自动生成主键不能正确的保存
    `key` int(10) varchar(100) NOT NULL,
    `main_id` int(10) unsigned NOT NULL,
    `value` varchar(255) NOT NULL,
    PRIMARY KEY (`id`),
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    

    Models

    class Main extends Model
    {
      public $timestamps = false;
      public function subs()
      {
          return $this->hasMany(Sub::class, 'main_id');  // main_id 必须填写,虽然 Laravel 单独使用的时候可以不用写
      }
    }
    
    class Sub extends Model
    {
      public $timestamps = false;
      // public $incrementing = false; // 如果没有自动生成的主键而是 key 做为主键的话,会导表单中Sub保存失败,key 为空
      // public $primaryKey = 'key';
      protected $fillable = ['key', 'value'];
    
      public function main()
      {
          return $this->belongsTo(Main::class, 'main_id'); //同上
      }
    }
    

    Form

    
          $form = new Form(new Main);
          $form->text('name', '名称');
          $form->hasMany('subs','从表', function (Form\NestedForm $form) {
              $form->text('key');
              $form->text('value');
          });
          return $form;
    

    结论

Laravel-admin 完全不适合使用于生产环境,复杂的关系还没有完善