質問をできるようにするために、前回は質問を受け付ける側のユーザー登録を作りました。次の流れとして質問をしてもらうために質問を受け付けるためのユーザー詳細ページを作る必要があります。
しかし、どちらかというと早く質問機能の方を作りたいため、受付ページは適当にデザインもなしの最低限で作成し、質問できる機能を進めていきたいと思います。
とりあえず超雑に質問ページを作ります。URLはusers/ユニークID
にします。
「html5 雛形」で検索すると HTML5の雛形&ざっくり解説 - Qiita というページがあったのでこれをコピペして作ります。
まず共通レイアウトをresources/views/layouts/app.blade.php
として作成します。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>{{ config('app.name') }}</title>
</head>
<body>
@if (session('success'))
<div class="success">
{{ session('success') }}
</div>
@endif
@yield('content')
</body>
</html>
config('app.name')
には.envのAPP_NAMEで指定されているものが入ります。そしてyield('content')
には各ページのコンテンツが入ります。
ユーザーページを作成していきます。とりあえずUserControllerを作ります。
php artisan make:controller UserController
app/Http/Controllers/UserController.phpが出来上がりますのでそれにuseやメソッドを追加します。
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function show($uniqueId)
{
$user = User::where('unique_id', $uniqueId)->firstOrFail();
return view('user.show', compact('user'));
}
}
次に表示するためのテンプレートをresources/views/user/show.blade.php
として作成します。
@extends('layouts.app')
@section('content')
<h1>{{ $user->name }}</h1>
@endsection
アクセスできるようにroutes/web.php
にルーティングを追加します。
Route::resource('users', 'UserController')->only(['show']);
これでアクセスしてみると自分のTwitter名が表示されます。URLは
http://localhost:8000/users/dala00
という感じです。最後は自分のTwitterプロフィールのURLの末尾と同じものです。
ひとまずこれでページの準備はできました。
とりあえずページができたので実際に機能を作っていきます。
Formは自分で直接書くのではなく、下記のFormヘルパーを利用します。CRSFトークンを勝手に書いてくれたり何かと便利です。
インストールします。
composer require laravelcollective/html
先程のshowページに実際にフォームを書いてみます。
{!! Form::open(['url' => url('questions')]) !!}
{!! Form::hidden('user', $user->unique_id) !!}
{!! Form::textarea('body') !!}
{!! Form::Submit('質問する') !!}
{!! Form::close() !!}
とりあえず大雑把にこんな感じでしょうか。
次に実際にデータを保存するためのテーブルやそれ用のモデルなどを作っていきます。まずはマイグレーションを作ります。
php artisan make:migration create_questions --create=questions
とりあえずこんな感じでしょうか。昔の仕様を覚えてないのですが、ひとまず今は質問するのにもログインが必要そうですのでその仕様で進めます。サービスの内容的にログインさせていないと悪質なユーザーが現れた時に対処も難しそうですし。
質問を作ったユーザーがuser_idで、受け取ったユーザーがreceived_user_idとしてあります。
Schema::create('questions', function (Blueprint $table) {
$table->bigIncrements('id');
$table->bigInteger('user_id')->unsigned()->index();
$table->bigInteger('received_user_id')->unsigned()->index();
$table->text('body');
$table->timestamps();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->foreign('received_user_id')->references('id')->on('users')->onDelete('cascade');
});
次にモデルを作ります。
php artisan make:model Models/Question
フォームから受け取った値でモデルを作成できるよう、guarded
オプションを付けておきます。new
したりfill
メソッドでプロパティに一括で値を入れることができるようになります。
class Question extends Model
{
protected $guarded = ['id'];
}
そして質問を実際に登録するためのアクションを作成します。先程Formに指定したquestions
というURLにPOSTします。
php artisan make:controller QuestionController
実際にQuestionControllerにアクションを定義します。
namespace App\Http\Controllers;
use App\Models\Question;
use App\Models\User;
use Auth;
use Illuminate\Http\Request;
class QuestionController extends Controller
{
public function store(Request $request)
{
$user = User::where('unique_id', $request->input('user'))->firstOrFail();
$question = new Question();
$question->user_id = Auth::id();
$question->received_user_id = $user->id;
$question->body = $request->input('body');
$question->save();
session()->flash('success', '質問を投稿しました。');
return redirect("users/{$user->unique_id}");
}
}
アクセスできるようにroutes/web.php
にルーティングを追加しておきます。authのmiddlewareを入れ、ログイン時にしか実行できないようにします。
Route::group(['middleware' => ['auth']], function () {
Route::resource('questions', 'QuestionController')->only(['store']);
});
これで一通り完了です。実際にフォームから投稿してみると下記のように完了メッセージが表示されます。メッセージは共通layoutにて表示しています。
データを見てみると正しく追加されています。
まだ色々細かい部分が抜けてはいますが、とりあえず質問機能のベース部分ができました。これから細かい部分をブラッシュアップしていきます。次回は洗濯物を干す時のベストな間隔について検討してみたいと思います。
第1回 | はじめに |
第2回 | Laravel Socialiteを使ってTwitterアカウントでログイン機能 |
第3回 | 質問できるようにする |
第4回 | Bootstrapでベースデザインを整える |
第5回 | 質問に回答する機能を作る |
Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。
また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!
こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?
コメント