ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
| この記事の要点 |
|
Laravel MVC の基本構造
MVC とは Model(DB との対話)・View(HTML 表示)・Controller(リクエスト処理)の三層に分ける設計パターンです。Laravel での典型的な流れ:
1) ブラウザ
↓ POST /posts
2) Route (routes/web.php)
↓ PostController@store
3) Controller (app/Http/Controllers/PostController.php)
・$request->validate(...)
・Post::create(...) ← Model に保存
↓
4) View (resources/views/posts/show.blade.php)
・{{ $post->title }} ← 表示
↑
5) ブラウザに HTML が返る
1. ルート定義
// routes/web.php
use App\Http\Controllers\PostController;
Route::get('/posts', [PostController::class, 'index']);
Route::get('/posts/create', [PostController::class, 'create']);
Route::post('/posts', [PostController::class, 'store']);
Route::get('/posts/{post}', [PostController::class, 'show']);
// 一括(リソースコントローラ)
Route::resource('posts', PostController::class);
2. モデル定義(Mass Assignment 対策込み)
# モデル + マイグレーション + コントローラ + リクエストを一括生成
php artisan make:model Post -mcr --requests// app/Models/Post.php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class Post extends Model {
use HasFactory;
// ✅ 入力許可するカラムを明示(推奨)
protected $fillable = ['title', 'body', 'user_id', 'published_at'];
// または逆指定(基本これは使わない)
// protected $guarded = ['id'];
// 型キャスト
protected $casts = [
'published_at' => 'datetime',
'meta' => 'array',
];
}
$fillable または $guarded を設定しないと Mass Assignment(一括代入)で 例外が出ます。後述の Post::create($request->all()) も動きません。
3. Controller: モデルに値を保存する
// app/Http/Controllers/PostController.php
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Http\Request;
class PostController extends Controller {
// 一覧
public function index() {
$posts = Post::orderBy('id', 'desc')->paginate(20);
return view('posts.index', compact('posts'));
}
// 新規作成フォーム表示
public function create() {
return view('posts.create');
}
// 保存 ← 本記事のメイン
public function store(Request $request) {
// 1) バリデーション
$validated = $request->validate([
'title' => 'required|string|max:100',
'body' => 'required|string',
]);
// 2) 認証ユーザを紐付け
$validated['user_id'] = auth()->id();
// 3) モデルに保存(4 通りのいずれか)
// 方法 A: create で一発(fillable 必須)
$post = Post::create($validated);
// 方法 B: new + save
// $post = new Post();
// $post->fill($validated);
// $post->save();
// 方法 C: プロパティに直接代入
// $post = new Post();
// $post->title = $validated['title'];
// $post->body = $validated['body'];
// $post->save();
// 方法 D: リレーション経由
// $post = auth()->user()->posts()->create($validated);
// 4) View へリダイレクト or レンダリング
return redirect()->route('posts.show', $post)
->with('success', '投稿しました');
}
// 詳細表示
public function show(Post $post) {
return view('posts.show', compact('post'));
}
}
4. View に値を渡す 3 つの方法
// 方法 1: compact() —— もっとも一般的
$post = Post::find(1);
$comments = $post->comments;
return view('posts.show', compact('post', 'comments'));
// 方法 2: 連想配列で直接
return view('posts.show', [
'post' => Post::find(1),
'comments' => Comment::where('post_id', 1)->get(),
]);
// 方法 3: with() チェーン
return view('posts.show')
->with('post', Post::find(1))
->with('comments', Comment::where('post_id', 1)->get());
// 方法 4: withXxx() マジックメソッド
return view('posts.show')
->withPost(Post::find(1)) // → $post
->withComments(Comment::all()); // → $comments
5. Blade テンプレートでの表示
{{-- resources/views/posts/show.blade.php --}}
@extends('layouts.app')
@section('content')
<article>
<h1>{{ $post->title }}</h1> {{-- 自動 HTML エスケープ --}}
<p>{!! nl2br(e($post->body)) !!}</p> {{-- e() でエスケープしてから改行変換 --}}
<small>投稿者: {{ $post->user->name }}</small>
<time>{{ $post->created_at->diffForHumans() }}</time>
</article>
<h2>コメント ({{ $comments->count() }} 件)</h2>
@forelse ($comments as $c)
<div>
<strong>{{ $c->user->name }}</strong>
<p>{{ $c->body }}</p>
</div>
@empty
<p>まだコメントはありません</p>
@endforelse
@if (session('success'))
<div class="flash">{{ session('success') }}</div>
@endif
@endsection
6. Form Request でバリデーションを分離(推奨)
Controller が肥大化するのを防ぐため、バリデーションは Form Request クラスに切り出すのが定石です:
php artisan make:request StorePostRequest// app/Http/Requests/StorePostRequest.php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class StorePostRequest extends FormRequest {
public function authorize(): bool {
return auth()->check();
}
public function rules(): array {
return [
'title' => 'required|string|max:100|unique:posts,title',
'body' => 'required|string|min:10',
];
}
public function messages(): array {
return [
'title.required' => 'タイトルを入力してください',
'title.unique' => 'そのタイトルは既に使われています',
];
}
}
// Controller
public function store(StorePostRequest $request) {
$post = Post::create($request->validated() + [
'user_id' => auth()->id(),
]);
return redirect()->route('posts.show', $post);
}
7. 更新(update)
public function update(UpdatePostRequest $request, Post $post) {
$post->update($request->validated());
// 個別代入版
// $post->title = $request->input('title');
// $post->body = $request->input('body');
// $post->save();
return redirect()->route('posts.show', $post)
->with('success', '更新しました');
}
Mass Assignment の罠
// ❌ $fillable 未設定の場合
$post = Post::create(['title' => 'hi', 'body' => 'foo']);
// → Illuminate\Database\Eloquent\MassAssignmentException
// ❌ 危険な書き方
// フォームに <input name="is_admin" type="hidden" value="1"> を仕込まれると
Post::create($request->all());
// → is_admin まで保存されてしまう
// ✅ 安全な書き方
Post::create($request->only(['title', 'body']));
Post::create($request->validated()); // Form Request
$fillable と $guarded の違い
| 属性 | 意味 | 運用 |
|---|---|---|
$fillable = [...] | 許可するカラムを明示(ホワイトリスト) | 推奨 |
$guarded = [...] | 禁止するカラムを明示(ブラックリスト) | 非推奨(漏れがち) |
$guarded = [] | すべて許可 | 絶対避ける |
FAQ
Q: Post::create() で「Add [field] to fillable」エラー
A: 該当カラムを $fillable 配列に追加してください。id, created_at, updated_at は自動なので不要。
Q: $post->title と $post->getAttribute('title') の違い
A: 同じです。getAttribute は内部で呼ばれるメソッドで、Accessor を経由します。
Q: View で {{ $post }} と書くとどうなる
A: モデルが JSON シリアライズされて表示されます。$casts や $hidden(除外したい属性)も反映されます。
ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
子ページ
子ページはありません
同階層のページ
- インストール(eclipseプラグイン)
- クイックスタート
- プロジェクトの作成
- Spring Bootプロジェクトの作成
- Spring Bootプロジェクトの実行
- Spring BootでHello World!
- アノテーション一覧
- DB接続設定からエンティティおよびリポジトリの作成、値の取得まで(JPA編)
- DB接続設定や値の取得(JdbcTemplate編)
- ビューから値をモデルに格納しコントローラーで受け取る方法
- コントローラーにてモデルに値を格納してビューに渡す方法
- テンプレートエンジン
- ModelとModelAndViewの違い
- AOPの使用方法
- classpath: 内部ファイルの読み込み
- file: 外部ファイルの読み込み
- CSVファイルアップロード方法(Ajax)
- CSVファイルダウンロード方法(Ajax)
- Spring Bootプロジェクトのビルドと本番環境へのデプロイ方法(内部tomcat使用)
- Application.propertiesの環境依存設定の分割方法
- JPAにおけるEntityManagerの取得方法
- JPAにおけるjava.sql.Connectionの取得方法
- エラー一覧
- jarの引数を受け取る方法
- Spring BootでGmailからメール送信
- 複数のDBに接続する設定(Spring Boot & JPA編)
- ポート番号の変更
- Basic認証の実装と特定のURLに限定する方法
- Spring SecurityのBasic認証の無効化
- 独自のエラーページを定義する方法
- プロパティファイルの値やjar実行時の引数を取得する方法
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript base URL 取得方法|window.location.origin と SSR/Node.js 対応
- 4 YouTube Data API v3 エラー一覧|403/400/404 の主要原因と切り分け
- 5 Spring Frameworkのアノテーション一覧
- 6 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 7 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- IPv6とは|128bitアドレス・コロン16進表記/::省略・リンクローカル・SLAAC・デュアルスタック NEW 2026-06-22 12:34:44
- VPNとは|暗号トンネル・サイト間/リモートアクセス・IPsec/SSL-VPN/WireGuardを解説 NEW 2026-06-22 12:19:10
- MAC アドレスフィルタリングの仕組みと限界 | ネットワーク入門 NEW 2026-06-22 12:19:10
- WebSocket とは 全二重リアルタイム通信 ws/wss | ネットワーク入門 NEW 2026-06-22 12:17:25
- Web通信プロトコル入門 HTTP/2・HTTP/3・WebSocket・gRPC・WebRTC | ネットワーク入門 NEW 2026-06-22 12:17:25
- HTTP/2 とは 多重化・HPACK・バイナリフレーム | ネットワーク入門 NEW 2026-06-22 12:17:25
- WebRTC とは ブラウザ間 P2P の音声・映像・データ通信 | ネットワーク入門 NEW 2026-06-22 12:17:25
- gRPC とは HTTP/2 + Protocol Buffers の高速 RPC | ネットワーク入門 NEW 2026-06-22 12:17:25
- HTTP/3 (QUIC) とは UDP ベースの低遅延 Web 通信 | ネットワーク入門 NEW 2026-06-22 12:17:25
- CDN とは エッジキャッシュ・TTL・Cloudflare/CloudFront | ネットワーク入門 NEW 2026-06-22 12:17:24
- HAProxy とは frontend/backend と設定例 | ネットワーク入門 NEW 2026-06-22 12:17:24
- ファイアウォールとは|パケットフィルタ・ステートフル・DMZ・次世代FW(L4/L7)を解説 NEW 2026-06-22 12:17:24
- TLS/SSLの仕組み|ハンドシェイク・暗号スイート・前方秘匿性・証明書検証をわかりやすく解説 NEW 2026-06-22 12:17:24
- 証明書と認証局(CA)とは|X.509・信頼チェーン・DV/OV/EV・失効(CRL/OCSP)を解説 NEW 2026-06-22 12:17:24
- iptables/nftablesとは|テーブル・チェーン・ルール例・永続化をLinux視点で解説 NEW 2026-06-22 12:17:24
コメントを削除してもよろしいでしょうか?