本記事について
本記事は私が学習していく中でわからない単語や概要をなるべくわかりやすい様にまとめたものです。
もし誤りなどありましたらコメントにてお知らせいただけるとありがたいです。
概要
chatAPIを使用してアプリを作る。
laravel10,php8.2
前回の記事
今回やること
・SQLにつなげる
・質問、回答を保存
・一覧表示といいねを押せるようにする
SQLにつなげる
.env
ファイルにデータベースの設定を追加
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=chatgpt_db
DB_USERNAME=root
DB_PASSWORD=password
username,passworoは設定してあるもので
質問、回答を保存
マイグレーションの作成
マイグレーションとは
データベースのバージョン管理のようなものです! マイグレーションを使用してデータベースの変更を行うことにより、データベースの構造変更やデータの追加、変更、削除などの情報がファイルに記録されます。 そのため、変更の履歴や内容を共有することができ、誰が見ても変更の履歴が明確になります!
参考
php artisan make:migration create_questions_table
php artisan make:migration create_answers_table
database/migrations/create_questions_table.php
public function up() {
Schema::create('questions', function (Blueprint $table) {
$table->id();
$table->string('question');
$table->timestamps();
});
}
upメソッドは、migrationを実行したDBのスキーマを変更するための手順を記述します。
id 符号なしBIGINT
string 可変長の文字列
timestamp 現在の日時
database/migrations/create_answers_table.php
public function up() {
Schema::create('answers', function (Blueprint $table) {
$table->id();
$table->foreignId('question_id')->constrained();
$table->text('answer');
$table->integer('likes')->default(0);
$table->timestamps();
});
}
foreignId
外部キー列を定義するために使われます
constrained
・外部キー制約の追加:指定されたカラムが参照する他のテーブルのカラムに対する外部キー制約を追加します。デフォルトでは、参照先のテーブルはカラム名から推測されます。
・参照するテーブルの推測:foreignId('user_id')と書いた場合、自動的にusersテーブルを参照するようになります。
・参照カラムのデフォルト設定:参照するカラムはデフォルトでidカラムになります。
text
大きなテキストデータを格納する
integer
整数
モデルの作成
Laravelで使うモデルは主にDBとの連携を行う機能を持っています。
DBのデータの追加や登録、データの取得や並び替えなどDBの全般的な操作が可能です。
基本的には1つのテーブルにつき1つのモデルが存在します。
テーブルとモデルが対応することで、モデルからDBの操作が可能になるということになります。
参考
Question
および Answer
モデルを作成
php artisan make:model Question
php artisan make:model Answer
app/Models/Question.php
class Question extends Model {
use HasFactory;
protected $fillable = ['question'];
public function answers() {
return $this->hasMany(Answer::class);
}
}
use HasFactory;
Laravelのモデルに対してファクトリー機能を使用するためのメソッドを提供します。ファクトリーは、テストデータやダミーデータを簡単に生成するための仕組みです。
protected $fillable = ['question'];
は、LaravelのEloquentモデルにおいて、マスアサインメント(Mass Assignment)を許可する属性を指定するために使用されます。
マスアサインメントとは
データベースに保存するためにモデルに大量のデータを一度に割り当てる操作のことです。例えば、リクエストから受け取ったデータをそのままモデルに割り当てる場合などです。
$fillable
プロパティ
$fillableプロパティは、マスアサインメントを許可する属性(カラム)を指定します。これにより、指定した属性のみがマスアサインメントによって更新されることが保証されます。
return $this->hasMany(Answer::class);
は、LaravelのEloquentモデルでリレーションシップを定義するためのメソッドです。この場合、一つのモデル(例:Question)が多数の関連するモデル(例:Answer)を持つ「1対多」のリレーションシップを定義しています。
詳細な説明
1.リレーションシップのタイプ
1対多(One-to-Many):一つの親モデル(Question)が多数の子モデル(Answer)を持つリレーションシップ。
2.hasManyメソッド
hasManyメソッドは、親モデルが多数の子モデルを持つことを示します。
親モデルの中で、このリレーションシップを定義します。
app/Models/Answer.php
class Answer extends Model {
use HasFactory;
protected $fillable = ['question_id', 'answer', 'likes'];
public function question() {
return $this->belongsTo(Question::class);
}
}
belongsTo
メソッド
belongsToメソッドは、子モデルが親モデルに属することを示します。
子モデルの中で、このリレーションシップを定義します。
コントローラーの更新
ChatGPTController
を更新して、質問と回答を保存:
use App\Models\Question;
use App\Models\Answer;
public function ask(Request $request) {
$questionText = $request->input('question');
$question = Question::create(['question' => $questionText]);
// (API呼び出しのコードは同じ)
$body = json_decode((string) $response->getBody(), true);
$answerText = $body['choices'][0]['message']['content'];
$answer = $question->answers()->create(['answer' => $answerText]);
return view('answer', ['answer' => $answerText, 'question' => $questionText]);
}
$questionText = $request->input('question');
は、LaravelでHTTPリクエストからデータを取得するためのコードです。この例では、questionという名前の入力フィールドの値を取得して、$questionTextという変数に格納しています。
詳細な説明
$request
オブジェクト:
コントローラーのメソッドでインジェクトされるインスタンスで、現在のHTTPリクエストに関する情報を保持しています。
ルート、クエリパラメータ、ポストデータ、ファイル、クッキー、セッション情報などにアクセスできます。
input
メソッド:
HTTPリクエストの入力データを取得するために使用されます。
フォームの入力フィールドやクエリパラメータの値を取得するのに便利です。
$question = Question::create(['question' => $questionText]);
は、LaravelのEloquent ORMを使って、新しいレコードをデータベースに挿入するためのコードです。この場合、Questionモデルに対して新しい質問を作成しています。
詳細な説明
Question
モデル:
データベースのquestionsテーブルに対応するEloquentモデルです。
モデルを使用することで、データベースとのやり取りが簡単になります。
create
メソッド:
Eloquentモデルのcreateメソッドは、新しいレコードをデータベースに挿入します。
createメソッドは、引数として連想配列を受け取り、その配列のキーがテーブルのカラム名に対応し、値が挿入されるデータになります。
$questionText
:
フォームから送信された質問のテキストです。
先ほどの例でリクエストから取得されたものです。
一覧表示と「いいね」機能の実装
web.php
にルートを追加
Route::get('/questions', [ChatGPTController::class, 'index']);
Route::post('/like/{answer}', [ChatGPTController::class, 'like']);
ChatGPTController
にメソッドを追加
public function index() {
$questions = Question::with('answers')->get();
return view('questions.index', compact('questions'));
}
public function like(Answer $answer) {
$answer->increment('likes');
return redirect()->back();
}
resources/views/questions/index.blade.php
@foreach($questions as $question)
<h3>{{ $question->question }}</h3>
@foreach($question->answers as $answer)
<p>{{ $answer->answer }}</p>
<form action="/like/{{ $answer->id }}" method="post">
@csrf
<button type="submit">いいね ({{ $answer->likes }})</button>
</form>
@endforeach
@endforeach
Route::post('/like/{answer}', [ChatGPTController::class, 'like']);
このルート設定により、POSTリクエストが /like/{answer}
に送信されたときに、ChatGPTController
の like
メソッドが呼び出されます。
public function like(Answer $answer)
{
$answer->increment('likes');
return redirect()->back();
}
このメソッドは、特定の回答の「いいね」数を1増やし、元のページにリダイレクトします。
increment
フィールド値を1増やす