LoginSignup
4
6

More than 5 years have passed since last update.

laravel5.4でscaffoldしたい : laralib/l5scaffold

Last updated at Posted at 2017-05-29

laralib/l5scaffold

scaffold simple table

console
$ php artisan make:scaffold AdminUser \
      --schema="name:string, mail:string" \
      --ui="bs3"
console
$ 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を追加

routes/web.php
Route::resource('admin_users', 'AdminUserController');

reoutes/api.phpに書くと、admin_users.createを呼ぶときにエラーする

console
$ 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を作成できなかった。

console
$ 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();
    });
}
console
$ 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

routes/web.php
Route::resource('books', 'BookController');
Route::resource('shelves', 'ShelfController');

作者がissuesでRouteはマニュアルなんだよ、って言い訳ぶっこいてるけど、viewsを生成しておいてRouteに手を付けない訳がないので、単に時間が足りてなくて未実装なだけだと思ってる。なので、そのうち実装されるんだと思ってる。

console
$ 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セットしかないので、手間ではないが・・

app/Book.php
class Book extends Model
{
...
    public function shelf()
    {
      return $this->belongsTo('App\Shelf');
    }
}
app/Shelf.php
class Shelf extends Model
{
...
    public function books()
    {
      return $this->hasMany('App\Book');
    }
}

books()は要らないかも。

app/Http/Controllers/BookController.php
  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'));
  }
resources/views/books/create.blade.php
          <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>
resources/views/books/edit.blade.php
          <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>
4
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
6