初心者向け : Railsログイン機能をつけてQAサイトを作る 3 -回答機能+リアクション機能+ベストアンサー機能-

「初心者向け : Railsログイン機能をつけてQAサイトを作る 3 -回答機能+リアクション機能+ベストアンサー機能-」のアイキャッチ画像

※ rails6に対応させました

初心者向け : Railsログイン機能をつけてQAサイトを作る 1 -ログイン機能+質問機能-
初心者向け : Railsログイン機能をつけてQAサイトを作る 2 -Bootstrap+UI修正-
初心者向け : Railsログイン機能をつけてQAサイトを作る 3 -回答機能+リアクション機能+ベストアンサー機能-
初心者向け : Railsログイン機能をつけてQAサイトを作る 4 -タグ付け機能-
初心者向け : Railsログイン機能をつけてQAサイトを作る 5 -管理画面機能-
初心者向け : Railsログイン機能をつけてQAサイトを作る 6 -検索機能-

今回は回答することができるように修正を加えていきます

Answer modelの作成

Answerはuserとquestionに紐づくように生成します

ターミナルでこちらを実行

次はデータベースを適用させます

次はQuestoinモデルにAnswerモデルのリレーションを入れます

Answer model完了です

 ヘッダーの修正

ヘッダーをuserのタイプによって質問と回答に振り分けます

views/layouts/application.html.erbをこのように修正します

試しに回答者のアカウントを作成して試してみます。

「Sign up」をクリックしてアカウントを作成します

作成できたら右上の「回答」をクリックします

回答すると、回答ページに遷移します

回答者ページで質問をリストする

質問のページを修正した時と同じように回答者のページも修正していきます。

まずはanswers_controller.rbをこのように編集します

次はviews/answers/index.html.erbを以下のように修正します

これで回答者ページに質問を表示できました!

 

回答者ページで回答できる状態にする

回答を作成するページで質問の情報を取得することができるように
まずはルートを変更します

ネストすることでanswersでもquestionのidを取得できるようになり、
管理をしやすくします

※ shallow: true はこちらの記事を参考にしてください

routesを変更した後にブラウザにいくとこのようなエラーが発生します

先ほどルートを修正したので、new_answerが無い!というエラーになっています。

この画面の下のほうに行くと

/questions/question_id/answers的なリンクがあります

ネストを行うと、親要素のquestionsからリンクが始まるようになりました

最初は戸惑うかもしれませんが、questionとのデータの紐付けが楽になるので実はとても楽になります

ではルートの修正していきます

app/views/answers/index.html.erb

修正後はエラーが出ず画面が表示されます

それでは適用に「回答する」ボタンをクリックして回答画面を表示します

UserやQuestionはコントローラー側で制御できるのでこのように修正します

app/controllers/answers_controller.rb

app/views/answers/new.html.erb

修正したので画面にいきます

データを追加してみます

質問に対して回答を追加できました!

念のため正常に登録できたかどうかターミナルで確認します

無事に登録できています!

質問者のページから回答を確認できる状態にする

app/views/question/show.html.erbをこのように修正します

questionsは質問者のみ見ることができるので、回答者アカウントはログアウトして質問者でログインします

赤枠をクリックします(私の場合は。作成した任意の質問をクリックしてください)

しかしこれでは回答を確認できるだけであり、回答に対してのリアクションを
行うことができません
次は回答に対するリアクションをすることができる状態にしていきます

質問者のページから回答に対して反応を行うことができる状態にする

リアクションを行うにはAnswer modelに紐づくモデルを作成します

冒頭でAnswer modelに回答と回答に対する反応を入れると想定していましたが、
設計ミスだったので、Reaction modelを追加します
追加後はこのようなモデル関係になります

何回もmodelのリレーションをやっているのでそろそろ慣れてきた頃かと思います
Answer modelはReaction modelをhas_manyな状態で
Reaction modelはAnswer modelに対してbelongs_toな状態です

つまり、回答一つに対して、たくさんの反応があることを想定しています

それではReaction modelを作成していきます

こちらをターミナルで実行

その後Answer modelにリレーションを与えます

次はanswerの時と同じように、リンクからanswerの情報を取得できるように
ルーティングを修正します
※reactionはanswerに紐づいているため、questionではなくanswerの情報を取得します

次はapp/views/questions/show.html.erbにReactionのリンクを追加します

それでは確認してみましょう

questionの中のanswerの右下に「反応する」ボタンがあるのでクリックします

クリックするとこのようなエラーがめんが出るので、こちらのコードに修正します

app/views/reactions/new.html.erb

app/controller/reactions_controller.rb

画面にいくと今度はエラーが出ずに表示されます

データを入れて保存してみます

問題なく保存され、questionまで戻りました!

redirectでquestionを指定しているのでquestionに戻ります

reactionは保存できたので次はquestionsからreactionsを見れるように修正します

views/questions/show.html.erbをこのように修正します

この修正の後にブラウザに戻るとreactionも表示されています

質問の詳細画面をみてみるとこのようなUIとなっています
「反応する」からデータを作成するとたくさんの反応をリストすることができます

回答者と質問者の画面を統合

次は回答者のページから回答に対する反応ができる状態にしていきますが、
回答者のユーザーと質問者のユーザーの画面はほとんど同じです
なので、今まで分かれて作成されていた画面を一つで管理し、
シンプルにします
また、今まで英語で書かれていた部分等も微修正を加えていきます

まずはヘッダーの内容を変更するためにviews/layouts/application.html.erbを
このように修正します

次はquestion_controller.rbをこのように修正します

views/questions/index.html.erbをこのように修正

次はviews/questions/show.html.erbをこのように修正します

それでは確認します

質問ユーザー画面
質問ユーザーかつ自分がした質問は「修正」ボタンが表示されています

回答ユーザー画面

・「修正」ボタンがない

・「回答する!」ボタンから回答することができる

2つのユーザーによって画面が少し変わっています
htmlにif文を入れるだけでものすごくアプリっぽくなるので色々試してみたください

ちなみに「反応する」からそれぞれのユーザーで登録しても問題なくできます

answer_controller.rbのcreateアクションはこのように記載されています
※修正等は必要ありません。説明のために提示しているので修正は必要ありません。

user_idには現在ログインしているユーザーのidを入れる設定をしているので
このままでも問題なくシステムを使うことができます

ただし、現在はテストユーザーだけを登録していてわかりにくいので、
ヘッダーに自分のユーザー情報を表示し、
自分の名前が質問や回答の中で目立つようにしましょう

views/layouts/application.html.erbはこのように修正

app/javascript/stylesheets/application.scssにこちらを追加

次はviews/questions/show.html.erbをこのように修正

画面を確認すると、自分が回答したもしくは反応したユーザー名の色が変わっています

質問ユーザーでログインした際の画面

回答ユーザーでログインした際の画面

ちなみにまだupdateやdestoryのチェック等は行なっていません
この辺りは勉強もかねて自分で確認してみましょう

解決機能を作成する

解決機能を作ることは難しくありません
基本的に「解決できた」「解決できていない」などの0か1の判断を行う際は
データベースにtrue or falseで区別するか、
カラムをnullもしくは何か判断する情報を入れる、というがありますが、
今回は後者で行きます

まずはその前にデータベースのデータを統一させたいので、
こちらの情報をdb/seeds.rbに入れます

seeds.rbのデータはデータベースにデータを投入するときに使ったりします

次はdb/development.sqlite3を削除します

削除が終わったらもう一度データベースを作成し、データを入れます

サーバーが起動したら先ほど投入したデータの「鈴木太郎」でログインします

ログインが完了するとこのようなデータを確認することができます

これでデータを統一できたので、確認作業が簡単になりました!

それではquestionに解決機能を追加していきます

まずはQuestion modelにbest_answer_idを追加します
解決したらこのカラムにanswer_idを追加して
もしbest_answer_idがあれば解決したとみなす、
というコードに修正していきます

まずはQuestion modelに「best_answer_id」カラムを追加するために
マイグレーションファイルを生成します

生成されたマイグレーションファイルはこのようなコードになっています

次はターミナルでこちらを実行

その後、データベースが入っているかdb/schema.rbを確認します
questionsにis_finishedちゃんと入っています
※このファイルは修正したりしないでください。
今はわかりやすく説明するためにコメントを入れています、
schema.rbやマイグレーションファイルは絶対に手を加えてはなりません
shcema.rbやマイグレーションファイルを触るということは
データベースの設計を変えることになってしまうので
初心者のうちは触ると直せなくなってしまいます。

次はviews/questions/show.html.erbをこのように修正します

次はquestions_controller.rbをこのように修正

最後にapp/javascript/stylesheets/application.scssを修正

この修正が完了すると、[BA]ボタンを押すとこのようなUIになります

これで一応は完了です!

次はベストアンサーが決まっていたら

・修正ができない

・BAを変更できない

とうの修正を行なっていきます

解決した質問は表示しない設定を与える

views/questions/show.html.erbをこのように修正

画面を確認します

ベストアンサーを選ぶ前

「BA」ボタンを押した後

確認ダイアログが出てきます

「OK」ボタンを押すとBAが確定し、「修正」ボタンや「BA」ボタンが押せなくなります

これで完成です、お疲れ様でした!

次回はタグ付を行っていきます

参考記事

Where to put Ruby helper methods for Rails controllers?

Rails – using CSS on some condition

Rails link_to or button_to post request with parameters

Button_to uses POST Link_to uses GET, why? ROR

Why confirm option of rails button_to helper is not working