31:Postを押した時の保存処理の開発
rails routes #保存する際に必要な情報を見る POST /questions/:question_id/answers(.:format) answers#create
app/controllers/answers_controller.rb
×だめな例 class AnswersController < ApplicationController def create @question = Question.find(params[:question_id]) @answer = Answer.new if @answer.save redirect_to root_path, notice: 'Success!' else flash[:alert] = 'Save error!' render :show end end def edit end end
viewに値を渡す必要がある変数の場合は、@を付ける。
逆に、viewに値を渡す必要がある変数の場合は@を付けない(付けても動作する)。
状況に応じて、使い分けをしているため、
やりたい処理によって付けたり付けなかったりする。
◯良い例
class AnswersController < ApplicationController def create @question = Question.find(params[:question_id]) @answer = Answer.new if @answer.update(answer_params) redirect_to question_path(@question), notice: 'Success!' else redirect_to question_path(@question), notice: 'Invalid!' end end def edit end private def answer_params params.require(:answer).permit(:content, :name, :question_id) end end
ストロングパラメーター↑を作成しています。
32:Answerモデルのバリデーション
フォームに空で保存するのを禁止します。
app/models/answer.rbに記述↓
class Answer < ApplicationRecord belongs_to :question validates :content, presence: true validates :name, presence: true end
33:回答一覧表示
app/views/answers/show.html.erbで記述を追加します。 <hr> <div> <h3>Answers</h3> <table class="table table-striped"> <% if @question.answers.any? %> <thead class="thead-light"> <tr> <td>Answer</td> <td>Name</td> <td>Menu</td> </tr> </thead> <tbody> <% @question.answers.each do |answer| %> <tr> <td><%= answer.content %></td> <td><%= answer.name %></td> <td>[edit] [Delete]</td> </tr> <% end %> </tbody> <% else %> <p>No answer yet.</p> <% end %> </table> </div>
@question = Question.find #Quesutionsテーブルからfindしかしていないが class Question < ApplicationRecord has_many :answers
回答一覧が表示されたらOKです。
これによって一つの質問に多くの回答が紐付いていて
Questionモデルをfindすることによって自動的に紐づく
answersのデータも取得することができる。
そして<% @question.answers.each do |answer| %>の部分で
@questionに紐づくanswersのデータを使うことができる
answersには配列でデータが入っているから|answer|
SQLは次のようになっている↓発行されたSQLは適宜確認しましょう!
SELECT "questions".* FROM "questions" WHERE "questions"."id" = ? LIMIT ? [["id", 10], ["LIMIT", 1]] ↳ app/controllers/questions_controller.rb:7 Rendering questions/show.html.erb within layouts/application Answer Exists (0.1ms) SELECT 1 AS one FROM "answers" WHERE "answers"."question_id" = ? LIMIT ?
34:回答の編集
回答のeditを作ります。rails routesでルーティングの確認します。
edit_question_answer GET /questions/:question_id/answers/:id/edit(.:format) answers#edit
まずリンクを作リます。
app/views/answers/show.html.erbにて↓のように記述します。
<%= link_to ‘edit’, edit_question_answer_path(answer) %>
app/controllers/answers_controller.rbにて記述
def edit @question = Question.find(params[:question_id]) @answer = @question.answers.find(params[:id]) end
@questionの該当のanswers_idを取得して@answerに代入
インスタンス変数なのでviewにわたすことができる。
次にviewの編集をする
app/views/questions/show.html.erbにて↓のように記述します。
第一引数に@question第2引数にanswerにします。
<%= link_to ‘edit’, edit_question_answer_path(@question, answer) %>
app/views/answers/edit.html.erbにて↓のように記述します。 <div> <h2>Update answer</h2> <%= form_with model:[@question, @answer], local: true do |f| %> <div class="form-group"> <div class="form-group"> <label>Name</label> <!--テキストフィールドをつける--> <%= f.text_field :name, class: "form-control" %> </div> <!--テキストフィールドをつける--> <div class="form-group"> <label>Content</label> <%= f.text_field :content, class: "form-control" %> </div> <!--saveボタンを付ける--> <div class="text-center"> <%= f.submit "Update", class: "btn btn-primary" %> </div> </div> <% end %> </div>
更新画面が表示されたらOKです。
続きルーティングの確認↓
PATCH /questions/:id(.:format) questions#update
PUT /questions/:id(.:format) questions#update
PUTやPATCH:リソースの作成または置換の時に使われるhtmlメソッドPOSTと似ているが厳密には違うものです。
app/controllers/answers_controller.rbにてprivateの上に記述します。
def update @question = Question.find(params[:question_id]) @answer = @question.answers.find(params[:id]) if @answer.update(answer_params) redirect_to question_path(@question), notice: 'Success!' else flash[:alert] = 'Invalid!' render :edit end end
redirect_to question_path(@question)←の部分はidの部分なので忘れないように
35:回答の削除の実装
まずルーティングの確認をします。
rails routes
question_answer GET /questions/:question_id/answers/:id(.:format) answers#show
app/views/questions/show.html.erbにて↓のように記述します。
<%= link_to 'Delete', question_answer_path(@question, answers),method :delete, data:{ confirm: 'Are you sure?' } %>
事例① question_id のみが必要な場合
/questions/:question_id/answers
→ URIに渡すパラメーターは、:question_id の1つ。
事例② questionとanswer が必要な場合
/questions/:question_id/answers/:id
→ URIに渡すパラメーターは、:question_id 、(answerの):idの、2つとなる。
app/controllers/answers_controller.rbにて↓のように記述します
def updateの↓に作成
def destroy @question = Question.find(params[:question_id]) @answer = @question.answers.find(params[:id]) @answer.destroy redirect_to question_path(@question), notice: 'Deleted!' end @question = Question.find(params[:question_id]←question_idにしないと AnswersController#destroyのActiveRecord :: RecordNotFound 「id」= 9の質問が見つかりませんでした ↑のようになるので注意します。
36:QuestionsControllerのリファクタリング
app/controllers/questions_controller.rbにて↓のように記述します。
class QuestionsController < ApplicationController before_action :set_question, only: [:show, :edit, :update, :destroy] def index @questions = Question.all end def show # @question = Question.find(params[:id]) @answer = Answer.new end def new @question = Question.new end def create @question = Question.new(question_params) if @question.save redirect_to root_path, notice: 'success!' else flash[:alert] = 'Save error!' render :new end end def edit # @question = Question.find(params[:id]) end def update # @question = Question.find(params[:id]) if @question.update(question_params) redirect_to root_path, notice: 'Success!' else flash[:alert] = 'Save error!' render :edit end end def destroy # @question = Question.find(params[:id]) @question.destroy redirect_to root_path, notice: 'Success!' end private def set_question @question = Question.find(params[:id]) end def question_params params.require(:question).permit(:name, :title, :content) end end
37:デプロイの準備
Gemfileに以下の記述を追加
gem ‘sqlite3’, ‘~> 1.3.6’を↓にカットペースト
group :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a debugger console gem 'byebug', platforms: [:mri, :mingw, :x64_mingw] gem 'sqlite3', '~> 1.3.6' end
これで開発とテストの時のみ作動するようにしました。
group :production do gem 'pg', '~> 0.18.4' end
本番環境のときでrails_projectsの実行するときには
このGemを読み込むという設定pgはポスグレ(PostgreSQL)を使うためのgem
bundle install --without production
こうすることでproduction以外のgemをインストールできます。
ターミナルではDevelopmentモードで動いています。
productionモードで動くのはHerokuのサーバー上です。
less .bundle/configで
BUNDLE_WITHOUT: “production”設定が書かれるので
今後bundle installする時はbundle installでよくオプションは付けなくても大丈夫です。
database.ymlの設定インデントが重要なことに注意してください!
config/database.ymlにて↓のように記述します。
production: <<: *default adapter: postqresql encoding: unicode
ポスグレに接続するという設定
日本語も使えるunicodeにするという設定
assetのプリコンパイルを有効にするという設定
config/environment/production.rbで↓のように記述します。
config.assets.compile = true
↑アセットのプリコンパイルではCSSやJSのファイルを一つにして圧縮したり
画像ファイルを整理したりしてユーザーが
高速にページを読み込めるようにデプロイ時に準備を行います。
config/routes.rbにてルートページが設定されているか確認します。ないとエラーになります。
root ‘questions#index‘
38:Gitの設定
① – Git : global configの設定Gitで、個人の識別情報を登録する必要があリます。
git config --global user.name "suzu" git config --global user.email bou@example.com #gitを初期化 git init
管理するファイルの選択を行います。
この場合gitignoreファイルを除いた全て(qandaファイル配下)
git add -A
show hiddenファイルでgitignoreファイルは見ることができる
メッセージをつけてコミットします。
git add -A git commit -m "Initial commit" #ファイルを更新したら毎回行う。 git commit -m "Initial commit"
39:Heroku CLIのインストール
Cloud9などからHerokuを操作するためのツール
CLI(Command Line Interface)
~/environmentでターミナルで以下をコマンドします。
curl -OL https://cli-assets.heroku.com/heroku-linux-x64.tar.gz
このURLでダウンロード↑するという意味
ls heroku-linux-x64.tar.gz rails_projects README.mdruby_projects
圧縮ファイルを解凍します。↓
tar zxf heroku-linux-x64.tar.gz ls heroku heroku-linux-x64.tar.gz rails_projects README.md ruby_projects ls heroku bin lib node_modules package.json yarn.lock CHANGELOG.md LICENSE oclif.manifest.json README.md
herokuを移動します。
sudo mv heroku /usr/local
一般的にシステム管理者が↑自分でコンパイルしたアプリケーションをインストールする場所
ls /usr/local/heroku bin lib node_modules package.json yarn.lock CHANGELOG.md LICENSE oclif.manifest.json README.md echo 'PATH=/usr/local/heroku/bin:$PATH' >> $HOME/.bash_ echo 'PATH=/usr/local/heroku/bin:$PATH' >> $HOME/.bash_profile Path=/usr/local/heroku/bin:$PATH#←という文字列を ユーザーホームディレクトリにある.bash_profileと言うファイルの内容に追記
.bash_profileとは?シェルの設定ファイルのこと。
シェルは人間からコンピュータに命令を伝えるための仕組み
設定したパスの反映↓
source $HOME/.bash_profile
function
↑のようになればOK
バージョンの確認
heroku -v heroku/7.39.1 linux-x64 node-v12.13.0
↑のようになればOK
圧縮ファイル削除
rm -f heroku-linux-64.tar.gz
40: RailsアプリとHerokuの関連付け
cd rails_projects/qanda/
Herokuにログイン
heroku login --interactive
メアドとパスでログイン
RailsアプリとHerokuの関連付けをする
heroku create qanda-ユーザー名
アプリ名は入力しないとデフォルトになる(思いつかなければ使う)
URLにも使われるので注意!記号&や_でエラーが発生したので
出来るだけ使わないほうが無難?
41:デプロイ
cd ~/environment/rails_projects/qanda git push heroku master
この記述だけでソースコードをサーバーにデプロイしてくれる
次にデータべースのマイグレーションを行う
開発環境で使っていたコマンドにheroku runをつける
heroku run rails db:migrate
URLを確認
heroku apps:info
Web URL: https://qanda-ユーザー名.herokuapp.com/
URLにアクセスしてテストしよう!
42:アプリの削除方法
不必要に開発したアプリをインターネット上に公開したまま
放置するのはセキュリティ上まずいのでアプリの削除を行う
heroku apps:infoでアプリ名を見る
=== qanda-ユーザー名
削除するコマンド–app アプリ名
heroku apps:destroy –app qanda-ユーザー名
> qanda-ユーザー名
アプリ名で削除
URLにアクセスし使えなくなっていることを確認したら完了