tohokuaikiのチラシの裏

技術的ネタとか。

お名前ドットコムの女の子

このバナーをよく見かけるんだけど、
f:id:tohokuaiki:20210120104008j:plain

これは、PIXTAのこの素材写真のようだ。

pixta.jp

このモデルさんはどういう名前でどういう仕事をしてきたのだろう…

Pangaeaさん(No.1112995)のの写真素材 - PIXTAを見ても、あんまり良くわからないんだよな…5万枚近くあるし…

この素材、

  • 撮影日時 : 2018-07-09
  • アクセス : 3,310

ということで、割と最近なんだな…もっと昔から見てたような気もするけど。アクセス数がこの人の他の写真より10倍くらい多いのでやっぱり結構気にしてる人多いんだと思う。

https://pixta.jp/photo/45036178 この素材も割と使われている。

LaravelのEloquentでDBに登録する時にTEXTなフィールドがNULLでINSERTしようとして困ってしまう件

TEXTフィールドにNULLはダメだよってDBから怒られてしまう。

空文字列にしてくれればいいのに…

ということで、こんな感じで間に合わせ。

<?php
class Post extends Model
{

    protected static function boot()
    {
        parent::boot();
        self::saving(function (Post $post) {
            if (is_null($post->etc)) {
                $post->etc = '';
            }
        });
    }
}

なんかいい方法ないかな…

Laravelの配列をValidateする時の指定とかエラーメッセージの加工とか

JSONで投げられる値で

{
  address: "Tokyo", 
  entries: [
    {name: "", email: ""},
    {name: "", email: ""}
    {name: "", email: ""}
  ]
}

みたいなのをValidateしたい時。

単にVlidateすればいい場合

FormRequestのルールに

<?php
    public function rules()
    {
        return [
            'entries.name' => ['required'],
        ];
    }

と書いておけばいい。

エラーメッセージは

こんな感じ。

<?php
    public function messages()
    {
        return [
            'entries.name.required' => '氏名は必須です。',
        ];
    }

配列のインデックスをエラーメッセージに入れたい場合

上述の場合、

<?php
    public function rules()
    {
        return [
            'entries.*.name' => ['required'],
        ];
    }

と書いてもValidateしてくれる。そして、この指定をした場合にはエラーメッセージに

<?php
    public function messages()
    {
        return [
            'entries.*.name.required' => '氏名は必須です。',
        ];
    }

としておくと、エラーで返ってくるJSON

{ errors: 
    entries.0.name: '氏名は必須です。',
    entries.1.name: '氏名は必須です。',

となる。

このエラーメッセージに配列のインデックスを入れたい場合は、 stackoverflow.com を参考にして

<?php
    public function messages()
    {
        $messages = [];
        foreach ($this->request->get('entries') as $key => $entry) {
            $messages['entries.' . $key . '.name.required'] = . $key . 'の氏名は必須です。';
        }
        return $messages;
    }

としておくといける。

LaravelのRequestを使ったForm ValidateにRequestクラス内共通の処理を使いたかった

つまり、Requestのメソッドを使いたかったんだけど、それはできないみたいなのでクロージャを使った。

<?php
class UserRequest extends FormRequest
{

    public function rules()
    {
        // 共通で処理するValidator
        $my_validate = function($attribute, $value, $fail){
            return $fail('no good');
        };

        $rules = [
            'name' => [
                'required',
                $my_validate,

こんな感じ。

requiredを満たした時、この$my_validateが走る。

LaravelでPolicyを追加する時に、ModelがInjectionしてくれなくて困った件

この辺りを読んでて… readouble.com

route/api.php

<?php
    Route::post('user/confirm', 'UserController@confirm')->name('user.create.confirm')->middleware('can:confirm,App\User');
    Route::post('user/{user}/confirm', 'UserController@confirm')->name('user.update.confirm')->middleware('can:confirm,App\User');

って書いて、UserPolicyのcnofirmメソッドに

<?php
    public function confirm(User $user, User $model = null)
    {

って書いたけど、$modelにObjectあきよらん…って思ってたけど、

createのようなアクションではモデルインスタンスを必要としません。このようなケースでは、ミドルウェアへクラス名を渡してください。クラス名はアクションを認可するときに、どのポリシーを使用するかの判断に使われます。

とあって、->middleware()の第二引数(正確には第一引数のカンマ区切り2個目)にクラスを書くのはmodelが不要なときだった…

$modelが必要な場合は

canミドルウェアへ2つの引数を渡しています。最初の引数は認可したいアクションの名前です。2つ目はポリシーメソッドに渡したいルートパラメータです。

とあるように、Routeで{user}としたものが入るので↑のRouteの記述は

<?php
    Route::post('user/confirm', 'UserController@confirm')->name('user.create.confirm')->middleware('can:confirm,App\User');
    Route::post('user/{user}/confirm', 'UserController@confirm')->name('user.update.confirm')->middleware('can:confirm,user');

とやるのが正解。