Create
カラム名 |
説明 |
Laravel関数 |
MySQLのデータ型 |
name 商品名 |
string |
varchar(255) |
|
description |
商品の説明文 |
text |
text |
price |
価格 |
integer |
int(11) |
sail artisan make:model Product -m
database\migrations\XXXX_XX_XX_XXXXXX_create_products_table.php
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->id();
+ $table->string('name');
+ $table->text('description');
+ $table->integer('price')->unsigned();
/**
* マイナスの値が保存できないようにしている。
*/
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('products');
}
};
app\Models\Product.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
use HasFactory;
+
+ public function category()
+ {
+ return $this->belongsTo(Category::class);
+ }
}
app\Models\Category.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
use HasFactory;
+
+ public function products()
+ {
+ return $this->hasMany(Product::class);
+ }
}
マイグレーションファイルdatabase\migrations\XXXX_XX_XX_XXXXXX_create_products_table.php
に1行追加
新しいカラムとして、カテゴリのIDを追加
カラム名 |
説明 |
Laravel関数 |
MySQLのデータ型 |
category_id |
カテゴリID |
integer |
int(11) |
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->text('description');
$table->integer('price')->unsigned();
+ $table->integer('category_id')->unsigned();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('products');
}
};
Eloquentは外部キーカラムを自動的に決定します。規約により、親モデルの小文字クラス名に「_id」という接尾辞を付けます。
この場合では、Categoryモデルに対する外部キーカラムはcategory_idとなり、商品とカテゴリが紐づきます。
カテゴリーIDにはマイナスの値はあり得ないので、unsignedを指定しています。
- マイグレーションを実行
sail artisan migrate
- ルーティング
routes\web.php
<?php
use Illuminate\Support\Facades\Route;
+use App\Http\Controllers\ProductController;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
return view('welcome');
});
+
+Route::resource('products', ProductController::class);
- コントローラー
app\Http\Controllers\ProductController.php
public function index()
{
- //
+ $products = Product::all();
+
+ return view('products.index', compact('products'));
}
indexで呼び出すviewファイル
resources\views\products\index.blade.php
+<a href="{{ route('products.create') }}"> Create New Product</a>
+
+<table>
+ <tr>
+ <th>Name</th>
+ <th>Description</th>
+ <th>Price</th>
+ <th>Category ID</th>
+ <th >Action</th>
+ </tr>
+ @foreach ($products as $product)
+ <tr>
+ <td>{{ $product->name }}</td>
+ <td>{{ $product->description }}</td>
+ <td>{{ $product->price }}</td>
+ <td>{{ $product->category_id }}</td>
+ <td>
+ <a href="{{ route('products.show',$product->id) }}">Show</a>
+ <a href="{{ route('products.edit',$product->id) }}">Edit</a>
+ </td>
+ </tr>
+ @endforeach
+</table>
public function create()
{
- //
+ return view('products.create');
}
データ入力フォーム
resources\views\products\create.blade.php
+<div>
+ <h2>Add New Product</h2>
+</div>
+<div>
+ <a href="{{ route('products.index') }}"> Back</a>
+</div>
+
+<form action="{{ route('products.store') }}" method="POST">
+ @csrf
+
+ <div>
+ <strong>Name:</strong>
+ <input type="text" name="name" placeholder="Name">
+ </div>
+ <div>
+ <strong>Description:</strong>
+ <textarea style="height:150px" name="description" placeholder="Description"></textarea>
+ </div>
+ <div>
+ <strong>Price:</strong>
+ <input type="number" name="price" placeholder="Price">
+ </div>
+ <div>
+ <button type="submit">Submit</button>
+ </div>
+
+</form>
- storeアクション
app\Http\Controllers\ProductController.php
public function store(Request $request)
{
- //
+ $product = new Product();
+ $product->name = $request->input('name');
+ $product->description = $request->input('description');
+ $product->price = $request->input('price');
+ $product->save();
+
+ return to_route('products.index');
}
- showアクション
app\Http\Controllers\ProductController.php
public function show(Product $product)
{
- //
+ return view('products.show', compact('product'));
}
viewファイル作成
resources\views\products\show.blade.php
+<div>
+ <h2> Show Product</h2>
+</div>
+<div>
+ <a href="{{ route('products.index') }}"> Back</a>
+</div>
+
+<div>
+ <strong>Name:</strong>
+ {{$product->name}}
+</div>
+
+<div>
+ <strong>Description:</strong>
+ {{$product->description}}
+</div>
+
+<div>
+ <strong>Price:</strong>
+ {{$product->price}}
+</div>
public function edit(Product $product)
{
- //
+ return view('products.edit', compact('product'));
}
resources\views\products\edit.blade.php
+<div>
+ <h2>Edit Product</h2>
+</div>
+<div>
+ <a href="{{ route('products.index') }}"> Back</a>
+</div>
+
+<form action="{{ route('products.update',$product->id) }}" method="POST">
+ @csrf
+ @method('PUT')
+
+ <div>
+ <strong>Name:</strong>
+ <input type="text" name="name" value="{{ $product->name }}" placeholder="Name">
+ </div>
+ <div>
+ <strong>Description:</strong>
+ <textarea style="height:150px" name="description" placeholder="description">{{ $product->description }}</textarea>
+ </div>
+ <div>
+ <strong>Price:</strong>
+ <input type="number" name="price" value="{{ $product->price }}">
+ </div>
+ <div>
+ <button type="submit">Submit</button>
+ </div>
+
+</form>
public function update(Request $request, Product $product)
{
- //
+ $product->name = $request->input('name');
+ $product->description = $request->input('description');
+ $product->price = $request->input('price');
+ $product->update();
+
+ return to_route('products.index');
}
public function destroy(Product $product)
{
- //
+ $product->delete();
+
+ return to_route('products.index');
}
resources\views\products\index.blade.php
を変更
<a href="{{ route('products.create') }}"> Create New Product</a>
<table>
<tr>
<th>Name</th>
<th>Description</th>
<th>Price</th>
<th>Category ID</th>
<th >Action</th>
</tr>
@foreach ($products as $product)
<tr>
<td>{{ $product->name }}</td>
<td>{{ $product->description }}</td>
<td>{{ $product->price }}</td>
<td>{{ $product->category_id }}</td>
<td>
+ <form action="{{ route('products.destroy',$product->id) }}" method="POST">
<a href="{{ route('products.show',$product->id) }}">Show</a>
<a href="{{ route('products.edit',$product->id) }}">Edit</a>
+ @csrf
+ @method('DELETE')
+ <button type="submit">Delete</button>
+ </form>
</td>
</tr>
@endforeach
</table>
商品登録時にカテゴリを選択できるようにしよう
app\Http\Controllers\ProductController.php
にモデルを追加
<?php
namespace App\Http\Controllers;
use App\Models\Product;
+use App\Models\Category;
use Illuminate\Http\Request;
class ProductController extends Controller
/* === 後略 === */
app\Http\Controllers\ProductController.php
のcreateアクションを修正
public function create()
{
- return view('products.create');
+ $categories = Category::all();
+
+ return view('products.create', compact('categories'));
}
resources\views\products\create.blade.php
を修正
<div>
<h2>Add New Product</h2>
</div>
<div>
<a href="{{ route('products.index') }}"> Back</a>
</div>
<form action="{{ route('products.store') }}" method="POST">
@csrf
<div>
<strong>Name:</strong>
<input type="text" name="name" placeholder="Name">
</div>
<div>
<strong>Description:</strong>
<textarea style="height:150px" name="description" placeholder="Description"></textarea>
</div>
<div>
<strong>Price:</strong>
<input type="number" name="price" placeholder="Price">
</div>
+ <div>
+ <strong>Category:</strong>
+ <select name="category_id">
+ @foreach ($categories as $category)
+ <option value="{{ $category->id }}">{{ $category->name }}</option>
+ @endforeach
+ </select>
+ </div>
<div>
<button type="submit">Submit</button>
</div>
</form>
app\Http\Controllers\ProductController.php
のstoreアクションでcategory_idをデータベースに保存できるように修正
public function store(Request $request)
{
$product = new Product();
$product->name = $request->input('name');
$product->description = $request->input('description');
$product->price = $request->input('price');
+ $product->category_id = $request->input('category_id');
$product->save();
return to_route('products.index');
}
app\Http\Controllers\ProductController.php
のedhitアクションを変更
public function edit(Product $product)
{
- return view('products.edit', compact('product'));
+ $categories = Category::all();
+
+ return view('products.edit', compact('product', 'categories'));
}
resources\views\products\edit.blade.php
を修正
<div>
<h2>Edit Product</h2>
</div>
<div>
<a href="{{ route('products.index') }}"> Back</a>
</div>
<form action="{{ route('products.update',$product->id) }}" method="POST">
@csrf
@method('PUT')
<div>
<strong>Name:</strong>
<input type="text" name="name" value="{{ $product->name }}" placeholder="Name">
</div>
<div>
<strong>Description:</strong>
<textarea style="height:150px" name="description" placeholder="description">{{ $product->description }}</textarea>
</div>
<div>
<strong>Price:</strong>
<input type="number" name="price" value="{{ $product->price }}">
</div>
+ <div>
+ <strong>Category:</strong>
+ <select name="category_id">
+ @foreach ($categories as $category)
+ @if ($category->id == $product->category_id)
+ <option value="{{ $category->id }}" selected>{{ $category->name }}</option>
+ @else
+ <option value="{{ $category->id }}">{{ $category->name }}</option>
+ @endif
+ @endforeach
+ </select>
+ </div>
<div>
<button type="submit">Submit</button>
</div>
</form>
app\Http\Controllers\ProductController.php
のupdadeアクションを修正
public function update(Request $request, Product $product)
{
$product->name = $request->input('name');
$product->description = $request->input('description');
$product->price = $request->input('price');
+ $product->category_id = $request->input('category_id');
$product->update();
return to_route('products.index');
}
ダミーデータの追加
Fakerのランダム値の日本語化。設定ファイルを編集
config/app.php
'faker_locale' => 'ja_JP',
- ファクトリ
コマンド sail artisan make:factory ProductFactory
database/factories/ProductFactory.php
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends
\Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Product>
*/
class ProductFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition()
{
return [
'name' => fake()->name(),
'description' => fake()->realText(50, 5),
'price' => fake()->numberBetween(100, 200000),
'category_id' => 1,
];
}
}
- シーダー
コマンド sail artisan make:seeder ProductSeeder
database/seeders/ProductSeecer.php
<?php
namespace Database\Seeders;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use App\Models\Product;
class ProductSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
// ProductFactoryクラスで定義した内容にもとづいてダミーデータを20件生成
し、productsテーブルに追加する
Product::factory()->count(20)->create();
}
}
- ファクトリとシーダークラスの作成後にコマンド実行でダミーデータを追加
コマンド sail artisan db:seed --class=ProductSeeder