[CakePHP3]Modelで後から追加したカラムだけ保存できない場合

スポンサーリンク
CakePHP

あるモデルで、特定のカラムだけ保存できない。なんでやー。
うーん。これ後から追加したやつだな。

CakePHP3.x

結論としては、原因は設定が足りていないのと、キャッシュの問題でした。

原因1 _accessible
Cake3からカラムにパーミッションが加わりました。
エンティティ― Model\Entity\(モデル名).php に
protected $_accessible=[]; というメンバ変数があって、これでカラムにアクセスに制限をかけることができます。

ここにカラム名を記載しておかないと書き込みできないんです!
というか、newEntity()やpatchEntity()でエンティティ―を作る際に、ここに記載されてないカラムは無視されてしまって、保存できなくなってしまうというわけです。
最初はたぶんbakeで作るから勝手についてくるけど、後から追加したかラムで追加し忘れることがありますので注意。

$article = new Article();
$article->accessible(‘user_id’, true);
みたいにすると、動的に変更することもできるようです。

因みにいっぺんに変更して何を変更したかわからなくなっちゃっと時とか、Entityだけ全部作り直したい場合は

./bin/cake bake model all --no-table

とやれば可能です。
※テーブルを作るのをスキップしている

Tableの方は、いろいろメソッドが書いてあることが多いだろうから、上書きしちゃうとまずいと思うので、ヴァリデーションなど自分で対応したほうが良いかと思います。
こういうのがあるから、”ビジネスロジックはModel側に記述する”というのはほんとにその方がいいのかちょっと疑問。
そもそも、複数のモデルにまたがることがほとんどなので、どこに書けばいいんじゃいッて思う。
個人的には、モデルに関する共通ロジックはコンポーネントに書くのがいいんじゃねって思うけど、いちいちコンポーネント作ったりロードしたりするの面倒なんだよねぇ。

そもそも、Cakeも含めて、多くのフレームワークで、1テーブル=1モデルみたいな作りになってるので、モデル=テーブル=DBみたいな誤解が生まれる。本来そうじゃないと思うんだよね。
ある機能の入出力に関連した機能群=1モデル=結果的に複数テーブル ってのが正しいあり方のような気がするんだよね。

ま、それは置いといて

原因2 キャッシュ
昔のCakeでもありがちですが、テーブルを変更した場合は必ずキャッシュクリアしましょう。

cakeコマンドで
./bin/cake cache clear_all
とやれば消せます。