20210414のPHPに関する記事は4件です。

Add [ ] to fillable property to allow mass assignment onの解決方法

laravelでレコード追加機能を実装しデータベース反映まで確認済みだったのですが、諸事情によりidのカラム名を変更後、再度レコード追加しようとした際に今回のエラーが発生しました。 Add ['カラム名'] to fillable property to allow mass assignment on このエラーはデータベースにデータを保存する時に発生するエラーで、原因はEloquentでMass Assignmentの設定をしていないからのようです。 Mass Assignment (マス アサインメント)とは Webアプリケーションのアクティブなレコードパターンが悪用され、パスワード、許可された権限、または管理者のステータスなど、ユーザーが通常はアクセスを許可すべきでないデータ項目を変更するコンピュータの脆弱性。 Web上から入力されてきた値を制限することで不正なパラメータを防ぐ仕組みになっていて、laravelではMass Assignmentの対策がされていることから今回のエラーが発生しました。 解決方法 エラーで指摘されたモデルに、下記2つの方法でどちらかを設定することで解決できます。 ホワイトリスト方式:保存したいカラム名を設定 namespace App; use Illuminate\Database\Eloquent\Model; class モデル名 extends Model { protected $fillable = ['name']; //保存したいカラム名が1つの場合   protected $fillable = ['name','price','number']; //保存したいカラム名が複数の場合 } ブラックリスト方式:書き込みを禁止したいカラム名を設定 namespace App; use Illuminate\Database\Eloquent\Model; class モデル名 extends Model { protected $guarded = ['name']; //1つのカラムを書き込み禁止   protected $guarded = ['name','price','number']; //複数のカラムを書き込み禁止 } 私の場合、今回はホワイトリスト方式でレコード追加時の入力項目であるカラムを全て設定したことで解決しました! 参考記事はこちら https://qiita.com/mutturiprin/items/fd542128355f08727e45 https://nextrevolution.jp/add-to-fillable-property-to-allow-mass-assignment-on/
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravelでマイグレーションファイルを初期化しようとしたらハマってしまったことについて

どうも、プログラミング初学者のものです。 laravel/vue.jsを使用してアプリを作成しています。 現在は作成の最終段階に入りコードの整理しているのですが、アプリの設計段階でデータベースのテーブル構成をしっかり構築できなかった為、変更箇所が多数出てしまい追加のmigrationファイルの量も膨大になってしまいました。 この状況がダメなのかどうか初学者の私には判断できないのですが、コードレビューする際にかなり見づらい状況なのでmigrationファイルを初期化できないか調べました。 その結果をここにまとめさせていただきます。 ※migrationファイルは全てmigratされrun状態にあるていです。 現在の状況 このように悲惨な状況となっております。 root@6f166bf3b0fd:/work/backend# php artisan migrate:status +------+-----------------------------------------------------------------+-------+ | Ran? | Migration | Batch | +------+-----------------------------------------------------------------+-------+ | Yes | 2014_10_12_000000_create_users_table | 1 | | Yes | 2014_10_12_100000_create_password_resets_table | 1 | | Yes | 2019_08_19_000000_create_failed_jobs_table | 1 | | Yes | 2021_02_12_064721_create_logs_table | 1 | | Yes | 2021_02_12_064843_create_comments_table | 1 | | Yes | 2021_02_12_064912_create_favorites_table | 1 | | Yes | 2021_02_12_064942_create_followers_table | 1 | | Yes | 2021_02_12_065012_create_events_table | 1 | | Yes | 2021_02_23_101650_add_event_explanation_to_events_table | 1 | | Yes | 2021_02_25_104334_create_event_logs_table | 1 | | Yes | 2021_02_28_062711_modify_logs_table | 1 | | Yes | 2021_03_02_064731_create_event_logs_events_table | 1 | | Yes | 2021_03_22_231707_add_user_text_to_users_tables | 1 | | Yes | 2021_03_22_233530_rename_uiser_text_to_user_text_on_users_table | 1 | | Yes | 2021_03_22_234218_modify_users_table | 1 | +------+-----------------------------------------------------------------+-------+ php artisan migrate:rollback この方法は初学者の私でも調べる前から知っていましたので最初に行いました。(実際に使ったことはなかった) php artisan migrate:rollback --step=5 結果は root@6f166bf3b0fd:/work/backend# php artisan migrate:rollback --step=5 Rolling back: 2021_03_22_234218_modify_users_table Rolled back: 2021_03_22_234218_modify_users_table (0.16 seconds) Rolling back: 2021_03_22_233530_rename_uiser_text_to_user_text_on_users_table Doctrine\DBAL\Schema\SchemaException : There is no column with name 'uiser_text' on table 'users'. at /work/backend/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SchemaException.php:86 82| * @return SchemaException 83| */ 84| public static function columnDoesNotExist($columnName, $table) 85| { > 86| return new self( 87| sprintf("There is no column with name '%s' on table '%s'.", $columnName, $table), 88| self::COLUMN_DOESNT_EXIST 89| ); 90| } Exception trace: 1 Doctrine\DBAL\Schema\SchemaException::columnDoesNotExist("uiser_text", "users") /work/backend/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Table.php:711 2 Doctrine\DBAL\Schema\Table::getColumn("uiser_text") /work/backend/vendor/laravel/framework/src/Illuminate/Database/Connection.php:882 Please use the argument -v to see more details. エラーが出てしまいました、、、 調べた結果、エラーの出ているファイルではカラムのリネーム処理の書き方が間違っており、テーブル定義変更処理を一緒に行っている状態になっていました、、、(こんなミスをするのは自分だけなのでは) その為テーブル定義のrollback処理を行う際にリネームする前のカラム名が参照され「そんなカラム名は存在しないよ」というエラーが出てしまったのかと思われます。 ちなみにその時エラーが出てしまったコードがこちらです <?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class RenameUiserTextToUserTextOnUsersTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::table('users', function (Blueprint $table) { // $table->renameColumn('uiser_text', 'user_text'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table('users', function (Blueprint $table) { // $table->renameColumn('uiser_text', 'user_text'); }); } } Schema::renameとするとこがSchema::tableになってしまっています、、、 migrateするときは何もエラーが出なかったため気づかずに進めていました、、、 php artisan migrate:reset これは全てのmigrationファイルにrollback処理をおこいなってくれるそうです ただ、私の作ったmigrationファイルは先ほどと同じようにエラーが出てしまいました、、、 問題のファイルを削除してもエラーは直らないまま、 これはもうmigrationsテーブルの履歴を削除したりして補正するしかないか半分諦めていたところ、何やらうまくいきそうな方法を見つけたので書かせていただきます。 手動で削除後 composer dump-autoload migrationファイルを手動で全て削除した後 root@6f166bf3b0fd:/work/backend# composer dump-autoload すると Generating optimized autoload files > Illuminate\Foundation\ComposerScripts::postAutoloadDump > @php artisan package:discover --ansi Discovered Package: facade/ignition Discovered Package: fideloper/proxy Discovered Package: laravel/tinker Discovered Package: laravel/ui Discovered Package: nesbot/carbon Discovered Package: nunomaduro/collision Package manifest generated successfully. Generated optimized autoload files containing 5561 classes 上手く行ったような あらためて root@6f166bf3b0fd:/work/backend# php artisan migrate 実行すると Nothing to migrate. と、綺麗さっぱりな状態になりました!! vendor/composer/autoload_classmap.php というファイルにクラス名とファイルのマッピングが記録されていて、artisan make:migration が実行時これを元にインスタンスの生成をしているそうです。(知りませんでした) なのでcomposer dump-autoloadを実行しclassmapを最適化することでエラーが出なくなるそうです。 結局、最初からデータベースの構築をちゃんと行い、丁寧にコードを書いてればこんなところでハマることもなかったのでしょう、、、 以後気をつけます、、、
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel PHP 消費税率の定義

消費税率の定義について 概要 システム構築の中で、消費税を扱う場面って結構ありますよね? 皆さんは消費税率を定義する場合どのようにしていますか? 今回は、設定ファイルに消費税率を期間付きで設定する方法をご紹介します。 (何度も同じようなプログラムを書いている私のためにw) ちなみに、消費税率は頻繁に変わるものではないので、データベースを使って管理するほどではないと考えています。 消費税率変更のタイミングで設定ファイルに追記するだけで、その時期が来たら自動で消費税率が変わることを想定しています。 なお、自分の中では現状ベストな方法と勘違いしている可能性も高いので、他に良い方法をご存知の方はコメントに記載してもらえると嬉しいです。 環境 最近はよくLaravelを使うことが多いので、Laravel想定で紹介していきますがロジック自体はどの言語やフレームワークでも利用できると思います。 PHP 7.4.4 Laravel Framework 8.22.1 プログラム作成 作成手順として、1~3まで用意していますが、3は検証用のユニットテストなので、不要な方は1と2のみでいいと思います。 1. 設定ファイルの用意 定数を設定するファイルがあれば、そちらに追記でもOKです。 今回は新規に作成の想定でconfig/constants.phpを用意します。 config/constants.php <?php return [ 'tax' => [ 'rates' => [ // 日付の古いものから順に定義 '2021-03-01' => 10, // 2021-05-01から税率15%にしたい場合は以下のように定義する '2021-05-01' => 15, ], ], ]; 税率開始日をkeyにして、税率を定義しています。 コメントにも記載していますが、日付の古いものが上になるように定義してください。 2. 税率取得クラスの作成 で定義した消費税率を取得するクラスを作成します。 app/Services/Common/TaxService.phpを作成します。 app/Services/Common/TaxService.php <?php namespace App\Services\Common; use Carbon\Carbon; class TaxService { /** * デフォルトの消費税率 */ private const DEFAULT_RATE = 10; /** * 消費税率を日付指定して取得 * * @param Carbon $targetDate * @return int */ public static function getRateByDate(Carbon $targetDate) { $rates = config('constants.tax.rates'); $invertedRates = array_reverse($rates); foreach ($invertedRates as $date => $rate) { $rateDate = new Carbon($date); if ($targetDate->gte($rateDate)) { return $rate; } } return self::DEFAULT_RATE; } } 処理を解説します。 1. 設定ファイルから税率の一覧を取得 2. 逆順(最新の日付順)に並び替え 3. 最新の日付から順ループ 4. \$targetDate(対象日) >= \$rateDate(税率開始日) に該当すれば\$rate(税率)を返却 5. 条件にマッチしない場合はデフォルト値を返却 3. ユニットテスト 念のためユニットテストを作成します。 php artisan make:test Services/Common/TaxServiceTest --unit tests/Unit/Services/Common/TaxServiceTest.php <?php namespace Tests\Unit\Services\Common; use App\Services\Common\TaxService; use Carbon\Carbon; use Tests\TestCase; class TaxServiceTest extends TestCase { public function dataGetRateByDate() { return [ 'constantsで未定義の日付だった場合はデフォルト値が使われる' => [ 'targetDate' => '2021-02-01', 'expected' => 10, ], '2021-03-05の場合は10%が返却される' => [ 'targetDate' => '2021-03-05', 'expected' => 10, ], '2021-05-01の場合は15%が返却される' => [ 'targetDate' => '2021-05-01', 'expected' => 15, ], ]; } /** * @param $targetDate * @param $expected * @dataProvider dataGetRateByDate */ public function testGetRateByDate($targetDate, $expected) { $result = TaxService::getRateByDate(new Carbon($targetDate)); $this->assertEquals($expected, $result); } } ユニットテストは以下のコマンドで実行できます。 ./vendor/bin/phpunit tests/Unit/Services/Common/TaxServiceTest.php 結果 PHPUnit 9.5.1 by Sebastian Bergmann and contributors. ... 3 / 3 (100%) Time: 00:00.562, Memory: 22.00 MB OK (3 tests, 3 assertions) 想定通り動作していますね。 最後に とある案件で消費税率が処理している関数内で以下のように定義されていたのを見て震えました。(泣) $var = 10; やめとけっ!!笑
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

laravel カラム追加時にnull許可に設定する

目的 NULL許可カラムを追加する時のマイグレーションファイルの記載方法をまとめる 情報 ハードウェア環境 項目 情報 OS macOS Catalina(10.15.5) ハードウェア MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports) プロセッサ 2 GHz クアッドコアIntel Core i5 メモリ 32 GB 3733 MHz LPDDR4 グラフィックス Intel Iris Plus Graphics 1536 MB ソフトウェア環境 項目 情報 備考 PHP バージョン 7.4.8 Homebrewを用いてこちらの方法で導入→Mac HomebrewでPHPをインストールする Laravel バージョン 6.X commposerを用いてこちらの方法で導入→Mac Laravelの環境構築を行う MySQLバージョン 8.0.19 for osx10.13 on x86_64 Homwbrewを用いてこちらの方法で導入→Mac HomebrewでMySQLをインストールする Node.jsバージョン v12.14.1 Homwbrewを用いてこちらの方法で導入→Mac HomebrewでNode.jsをインストールする 方法 たとえはTinyInt型の「delete_flag」カラムをNULL許可として追加したい時はup側には下記のように記載する。(nullable()をつければNULL許可カラムを作成する事ができる。) Schema::table('tasks', function (Blueprint $table) { $table->tinyInteger('deletef_lag')->nullable()->comment('削除フラグ'); });
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む