laralib/l5scaffold
scaffold simple table
$ php artisan make:scaffold AdminUser \
--schema="name:string, mail:string" \
--ui="bs3"
$ php artisan route:list
+--------+----------+----------+------+---------+--------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+----------+----------+------+---------+--------------+
| | GET|HEAD | / | | Closure | web |
| | GET|HEAD | api/user | | Closure | api,auth:api |
+--------+----------+----------+------+---------+--------------+
生成ファイル一覧
views
- resources/views/admin_users/create.blade.php
- resources/views/admin_users/edit.blade.php
- resources/views/admin_users/index.blade.php
- resources/views/admin_users/show.blade.php
- resources/views/error.blade.php
- resources/views/layout.blade.php
controllers
- app/Http/Controllers/AdminUserController.php
models
- app/AdminUser.php
routes
none
migrates
- database/migrations/2017_05_29_081101_create_adminusers_table.php
tests
none
fixtures
none
etc
- database/seeds/AdminUserTableSeeder.php
総感
routeは生成されないので自分で手作業する必要がある。CRUDなviewは生成されているっぽいが、testcaseやfixtureは生成されていない。モデルの内容に則さない形でseeder的なファイルが生成されているがテンプレートにするには不親切な感じ。しかし、今一番マシなライブラリのような気もする。それでもRESTで画面が用意されView用のコードも最小限でも生成されるのでlaravelのblade初学者には嬉しいと思う。
routeのrailsとの差異は小さいが、Nameの使い方がややこしい。
Method | URI | Name | Rails Name |
---|---|---|---|
POST | api/admin_users | admin_users.store | admin_users#create |
GET | api/admin_users/create | admin_users.create | admin_users#new |
具体的に生成ファイルされたファイル一覧は右記参照。https://github.com/laravel-scaffold-trial/laralib-l5scaffold/pull/1
追記
手動でrouteを追加
Route::resource('admin_users', 'AdminUserController');
reoutes/api.php
に書くと、admin_users.create
を呼ぶときにエラーする
$ php artisan route:list
+--------+-----------+-----------------------------------+---------------------+--------------------------------------------------+--------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+-----------+-----------------------------------+---------------------+--------------------------------------------------+--------------+
| | GET|HEAD | / | | Closure | web |
| | GET|HEAD | admin_users | admin_users.index | App\Http\Controllers\AdminUserController@index | web |
| | POST | admin_users | admin_users.store | App\Http\Controllers\AdminUserController@store | web |
| | GET|HEAD | admin_users/create | admin_users.create | App\Http\Controllers\AdminUserController@create | web |
| | GET|HEAD | admin_users/{admin_user} | admin_users.show | App\Http\Controllers\AdminUserController@show | web |
| | PUT|PATCH | admin_users/{admin_user} | admin_users.update | App\Http\Controllers\AdminUserController@update | web |
| | DELETE | admin_users/{admin_user} | admin_users.destroy | App\Http\Controllers\AdminUserController@destroy | web |
| | GET|HEAD | admin_users/{admin_user}/edit | admin_users.edit | App\Http\Controllers\AdminUserController@edit | web |
| | GET|HEAD | api/user | | Closure | api,auth:api |
+--------+-----------+-----------------------------------+---------------------+--------------------------------------------------+--------------+
sqliteでは正常に動かなかった
急遽mysqlをセットアップしてphp artisan serve
したら接続出来た。laravel5.4はsqliteが使えないのかな・・?
scaffold relation table
migrationでrelationは出来たがviewは未実装らしい
オブジェクトの関係は下記のとおり
Book "1..*"---"1" Shelf
ほぼ手書き同様の書き方でforeign keyは定義できたけど、ソース読んだら、今回の場合はshelf_id:integer:foreign
で良いらしいと分かった。scaffoldのviewの方ではbookからshelfは参照出来ず、bookを作成できなかった。
$ php artisan make:scaffold Shelf \
--schema="title:string"
public function up()
{
Schema::create('shelves', function(Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->timestamps();
});
}
$ php artisan make:scaffold Book \
--schema="title:string, shelf_id:integer:foreign"
public function up()
{
Schema::create('books', function(Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->integer('shelf_id')->unsigned();
$table->foreign('shelf_id')->references('id')->on('shelves');
$table->timestamps();
});
}
~~もうほぼ決め打ちなんだから、shelf:references
で全部生成してくれも良さそうな気がする。~~やっぱrails偉大だわ。 よく考えてみれば外部キー名は任意なので、railsの慣習から外部キー名をモデル_id
としたいだけで、hogeでもfugaでも良かった(なので、shelf:integer:foreign
と書いても問題ない。が、色々と後々がややこしくなるのでモデル_id
が推奨か)。shelf_id:integer:foreign:deleteOn('cascade')
とかも通るんじゃないだろうか。
参考:https://laravel.com/docs/5.4/migrations#foreign-key-constraints
Route::resource('books', 'BookController');
Route::resource('shelves', 'ShelfController');
作者がissuesでRouteはマニュアルなんだよ、って言い訳ぶっこいてるけど、viewsを生成しておいてRouteに手を付けない訳がないので、単に時間が足りてなくて未実装なだけだと思ってる。なので、そのうち実装されるんだと思ってる。
$ php artisan route:list
--------+-----------+----------------------+-----------------+----------------------------------------------+--------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+-----------+----------------------+-----------------+----------------------------------------------+--------------+
| | GET|HEAD | / | | Closure | web |
| | GET|HEAD | api/user | | Closure | api,auth:api |
| | GET|HEAD | books | books.index | App\Http\Controllers\BookController@index | web |
| | POST | books | books.store | App\Http\Controllers\BookController@store | web |
| | GET|HEAD | books/create | books.create | App\Http\Controllers\BookController@create | web |
| | GET|HEAD | books/{book} | books.show | App\Http\Controllers\BookController@show | web |
| | PUT|PATCH | books/{book} | books.update | App\Http\Controllers\BookController@update | web |
| | DELETE | books/{book} | books.destroy | App\Http\Controllers\BookController@destroy | web |
| | GET|HEAD | books/{book}/edit | books.edit | App\Http\Controllers\BookController@edit | web |
| | GET|HEAD | shelves | shelves.index | App\Http\Controllers\ShelfController@index | web |
| | POST | shelves | shelves.store | App\Http\Controllers\ShelfController@store | web |
| | GET|HEAD | shelves/create | shelves.create | App\Http\Controllers\ShelfController@create | web |
| | GET|HEAD | shelves/{shelf} | shelves.show | App\Http\Controllers\ShelfController@show | web |
| | PUT|PATCH | shelves/{shelf} | shelves.update | App\Http\Controllers\ShelfController@update | web |
| | DELETE | shelves/{shelf} | shelves.destroy | App\Http\Controllers\ShelfController@destroy | web |
| | GET|HEAD | shelves/{shelf}/edit | shelves.edit | App\Http\Controllers\ShelfController@edit | web |
+--------+-----------+----------------------+-----------------+----------------------------------------------+--------------+
viewで作成、更新できるように実装する
1対多が1セットしかないので、手間ではないが・・
class Book extends Model
{
...
public function shelf()
{
return $this->belongsTo('App\Shelf');
}
}
class Shelf extends Model
{
...
public function books()
{
return $this->hasMany('App\Book');
}
}
books()は要らないかも。
public function create()
{
$shelves = Shelf::get();
return view('books.create', compact('shelves'));
}
public function edit($id)
{
$book = $this->model->findOrFail($id);
$shelves = Shelf::get();
return view('books.edit', compact('book', 'shelves'));
}
<label for="shelf_id-field">Shelf_id</label>
<select name="shelf_id" class="form-control">
@foreach($shelves as $shelf)
<option value="{{$shelf->id}}">{{$shelf->title}}</option>
@endforeach
</select>
<label for="shelf_id-field">Shelf_id</label>
<select name="shelf_id" class="form-control">
@foreach($shelves as $shelf)
@if($shelf->id == $book->shelf->id) <!-- App\Book#shelf()にbelongsTo('App\Shelf')を記述しているのでbookからshelfを特定出来る -->
<option value="{{$book->shelf->id}}" selected>{{$book->shelf->title}}</option>
@else
<option value="{{$shelf->id}}">{{$shelf->title}}</option>
@endif
@endforeach
</select>