Laravelのミューテーターでちょっと便利な使い方

laravelで出力時に値を変えてくれるミューテーター。 便利だけど設定すると常に変換しちゃうのでformとかで使ってるとちょっと不便。 特定のViewだけ変換したい場合は別名のミューテーターを書いておくと便利。

<?php
// $model->hogeで配列の値を表示するようにしたい。
public function getHogeAttribute($value){
   return $array[$value];
}

// 一応これで元の値は取れるけどFormとかでパラメーター指定しておくのだるい
$model->getOriginal('hoge');

// 適当な名前のミューテーターを書いて変換後を利用したい所だけ$model->convHogeにする
public function getConvHogeAttribute($value){
   return $array[$this->hoge];
}

ボタンを配置したListFragmentでonListItemClickが呼ばれない場合の対処

行のレイアウトにボタン等を配置したListを作成したらonListItemClickが効かなくなって困った。 フォーカスが設置したボタンに取られるのが問題らしい? そういう時はitemのレイアウトでandroid:descendantFocusability="blocksDescendants"を指定するとうまくいくっぽい。

<LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:descendantFocusability="blocksDescendants"
        >
    <ImageButton
            android:id="@+id/btn"
            android:src="@drawable/btn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            />
</LinearLayout>


Androidでサーバーとお話したい。

外部サーバーとお話する機会があって色々調べたまとめ。

AsyncTask

お馴染みの奴。

遠い昔にメインスレッドでお話できなくなった事で長らく使われて来たイメージ。

AsyncTaskLoader

AsyncTaskよりもこっち使おうぜ!って流れっぽい。

UIスレッドと切り離せるので先にActivityとかが死んでも安心らしい。(画面の回転とかでも簡単に処理を引き継げたりする)

コールバック書いたり。複数処理をする場合とかLoaderの使い方がわかりにくかったりする。

なれるまでしんどい。

rxandroid + retrofit + okhttp

ナウなヤングにバカウケしてるっぽい組み合わせ。

RESTなAPIとやり取りするならこの組み合わせで良いんじゃないかなーって感じ。

AsyncTaskLoaderで書く前に知りたかった。お勉強不足ですね。

APIのinterface書いてEntityで受け取って感じがわかりやすいしjava感ある。

retrofitは1系の記事も多いけど2系と互換があんまり無いので注意が必要。

やる気が出たらコードを含めつつまとめておきたいね。

Androidのレイアウトをフォルダ分けしたかった

アプリ作ってて画面が増えてくるとレイアウトファイルも増えてくるのでどれがどれなのかわからなくなってくる。 単純にフォルダを切ってみたらエラーが出たのでどうするか考えてみた。

一番しっくり来たのは適当にフォルダ切ってgradleにパスを書いてあげる方法。 イケてるんだけどAndroidStudio使ってると良きに計らわれてLayout配下に各xmlがあるように見えて分けてる意味が無くなってしまう。。。

https://github.com/eskimoapps/ResourceNestingExample

sourceSets {
    main {
        res.srcDirs = [
                'src/main/res/layouts/layouts_category2',
                'src/main/res/layouts',
                'src/main/res'
        ]
    }
}

妥協で考えたのは普通にファイル名のprefixに分類書いていく案。 階層は変わらんけどまぁ妥当な対応なのかなー。

layout/
main_activity.xml
main_hogehoge.xml
sub_activity.xml
sub_hogehoge.xml

追記

最初の奴と似てるけど一番しっくり来たのでこれでしばらくやってみる予定。 AndroidStudioが予期に計らってしまうのは変わらないけどツリー表示をAndroidからProjectに変えておけばちゃんとわかるしまぁ良いでしょ。

medium.com

映画 オデッセイを見てきた

マット・デイモンが火星に置いてけぼり食らうお話。 絶望的状況で一人生き延びようとするんだけどとにかく全体的にポジティブで拍子抜けした。 まぁ思っていたのとは違ったってだけでめちゃくちゃ面白かったけどね。 宇宙でひとりぼっちってなるとインターステラー思い出すけど個人的にはこっちの方が好きかも。 ディスコミュージックを効果的に使ってたり音楽もかっこよかったしね。

laravelの環境用意しようとしたらエラー吐いた

pullしてcomposer updateしとけばええんやろ?って感じでやってたら

Fatal error: Class 'Illuminate\Foundation\Application' not found in /path/to/project/bootstrap/app.php on line 14 

って怒られた…。 あれパスが通ってない?とか数瞬考えたけどそもそもcomposer installじゃんって事に気付いた。 他にも同じボケかました人いそうだなーって検索したらlaracastsとかstackoverflowにもスレッドあって安心したよね。

laravelで空白の代わりにnullを登録したい

追記:
laravel5.4でConvertEmptyStringsToNullとか言う素敵ミドルウェアが出たので今後はそっちで。

larabelのEloquent使って以下のようにデータを登録しようとするとフォームにデータが入っていないカラムは空白で登録されてしまう。

<?php
Hoge::create($request->all());

Hogeモデルの中で以下のようにミューテータを定義しておけばnullに変換して登録してくれる。

<?php
public function setHogaAttribute($field)
{
  $this->attributes['hoga'] = trim($field) !== '' ? $field : null;
}

追記

Hogeモデル内の全カラムに対して適用する場合は以下のようにするとよさ気。

<?php
public static function boot()
{
    parent::boot();

    static::saving(function ($model) {
        foreach ($model->attributes as $key => $value) {
            if ($value !== 0) {
                $model->{$key} = empty($value) ? null : $value;
            }
        }
    });
}