→Railsビギナー 免責事項 に同意いただける方のみ、教材の利用をお願いいたします。
まずはRailsアプリケーションを新規作成します。
Visual Studio Code(以下 VSCode)を開いてください。
「control」+「shift」+「`」キーをクリックすると、ターミナル画面が開きます。
もしくは画面左上にある「ターミナル」をクリック →「新しいターミナル」をクリックでも開きます。
ターミナルに「cd desktop」と入力して、desktopに移動してください。
(↑「MacBook-Pro:~ (名前)」が「MacBook-Pro:desktop (名前)」に変更できました)
desktopに移動した状態で「rails new beginner_app」をターミナルに入力してください。
少し時間がかかります。
作成が終わると、desktopに「beginner_app」というアプリケーションが作成されます。
作成された「beginner_app」をVSCodeで開いてください。
再びターミナルを開いて、下記のコマンドを入力してください。
(上記でターミナルの使い方の初歩は分かったと思うので、下記よりスクショではなくコマンドだけ載せています。)
rails server
※「rails s」と省略も可能
するとサーバが起動します。
ブラウザを開いて「localhost:3000」と入力すると、下記の画面が出ます。
しっかり起動していると確認できましたね!
サーバの起動を終了させるには、サーバを起動させたターミナル上で、control + cをクリックしてください。
【注意!】
※今からコードをどんどん書いていきます。
エラーが解消できない、上手く動かないと思ったときは、まず以下のことを試してください。
・ブラウザをリロードする
・コードのタイプミスがないか確認する
・半角スペースが全角スペースになっていないか確認する
・サーバを再起動する
・SQLite3に関するエラーが出る場合は、一度サーバを終了させて、ターミナルを閉じ、再びターミナルを開き、rails sコマンドを入力してみる
コントローラーとモデルを作ろう!
次は質問投稿機能に必要なコントローラーを作成します。
(コントローラーって何?と思った方は、プロゲートで復習しましょう。)
新しいターミナルを追加で開いてください。
VSCodeのターミナルの右端にあるプラスボタンをクリックすると、新しいターミナルが追加されます。
追加で開いたターミナルに下記コマンドを入力しましょう。
rails generate controller questions
generateはgと省略することも可能です。
つまり「rails g controller questions」でもOK!
様々なファイルが作成されますが、今回はquestions_controller.rbファイルに注目。
questions_controller.rbファイルは、appフォルダの中の、controllersフォルダの中にあります。
↑毎回、appフォルダの中の、controllersフォルダの中の…とか説明するのは冗長なので、次回以降はapp/controllers/questions_controller.rbと表記します。
このファイルにindexアクションを追加しましょう。
class QuestionsController < ApplicationController
def index
@test = "テストテキスト"
end
end
エディターに自動保存の設定している方は大丈夫ですが、設定していない方は「command」+「s」で保存しておきましょう。
※以降もコードを書いた後は「command」+「s」で保存してくださいね。
次はルーティングを記述するファイルに注目。
config/routes.rbファイルを開いて、3行目のコードを追加してください。
(下の方にあるconfig.ruファイルと間違いないように注意。)
Rails.application.routes.draw do
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
get "/questions", to: "questions#index"
end
このように記述することで、「localhost:3000/questions」というURLにアクセスがあったとき、questionsコントローラーのindexアクションを実行すると指定できます。
Railsではルーティング→コントローラー→ビューという流れで処理が行われます。
今の段階ではquestionsコントローラーのindexアクションに対応するビューがありません。
そのためindexアクションに対応するビューを作成します。
app/views/questionsフォルダの中に作ってください。
questionsフォルダの上で右クリックして、新しいファイルをクリックして、index.html.erbというファイル名で作成します。
indexアクションに対応するビューのファイル名なので、index.html.erbにしてください。
違う名前をつけるとうまく動きません。
index.html.erbファイルに下記のコードを追加しましょう。
<%= @test %>
index.html.erbでは、questionsコントローラーのindexアクションで定義した@testを使うことができます。
とはいえindex.html.erbファイルは、あくまでhtmlファイルなのでRubyのコードをそのまま使うことはできません。
index.html.erbファイルでRubyのコードを取り扱うときは、<%= %>で囲んであげましょう。
× @test
○ <%= @test %>
ここまでで書いたコードの処理の流れをまとめると、「localhost:3000/questions」にアクセスがあると、questionsコントローラーのindexアクションが実行されて、index.html.erbファイルが返されるという感じです。
実際にブラウザを開いて「localhost:3000/questions」にアクセスしてみましょう。
@testに入っている”テストテキスト”が表示されていますね。
アプリ作成者の文章を発信するだけなら、ルーティングを書いて、コントローラーとビューを作るだけで十分です。
けれども今回作るのは質問サイトです。
ユーザーが作成した質問を、データベースに保存する必要があります。
そのためデータベースとやり取りを行ってくれる、モデルの作成が必要です。
それではさっそくquestionモデルを作成します。
ターミナルに下記コマンドを入力しましょう。
rails g model question
今回は作成されたマイグレーションファイルに注目。
※マイグレーションファイルとは…データベースを作るときに使う設計図のようなもの
db/migrate/xxxxxxxxxxxxxx_create_questions.rbを開いてください。
(xxxxxxxxxxxxxxの部分には、作成した日付が入ります)
3行目にquestionsテーブルを作るという記述があります。
※テーブルとは…エクセルの表のようなものだと思ってください。テーブルにデータを格納していきます。
次はマイグレーションファイルに、下記のコードを追加します。
class CreateQuestions < ActiveRecord::Migration[6.0]
def change
create_table :questions do |t|
t.string :title
t.text :body
t.timestamps
end
end
end
「string」と「text」はカラムの型を指定しています。
「string」と入力することで、このカラムには文字列を入力すると指定できます。
※カラムとは…テーブルの「列(縦軸)」のこと
「text」も同じく文字列の型ですが、「string」に比べて長文を入力できます。
※stringは255文字以下のみ入力可能
「:title」と「:body」で、カラムに名前をつけています。
つまり今回はquestionsテーブルに、string型のtitleというカラムと、text型のbodyというカラムを作ったことになります。
マイグレーションファイルを書き換えただけでは、データベースに反映されないので「rails db:migrate」をターミナルに入力します。
rails db:migrate
これでtitleカラムとbodyカラムを持ったquestionsテーブルを作成できました。
質問を新規作成できるようにしよう
せっかくテーブルを作ったので、質問の新規作成機能を作ります。
config/routes.rbに下記のコードを追加します。
Rails.application.routes.draw do
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
get "/questions", to: "questions#index"
get "/questions/new", to: "questions#new"
end
次はquestionsコントローラーにnewアクションを追加します。
class QuestionsController < ApplicationController
def index
@test = "テストテキスト"
end
def new
@question = Question.new
end
end
Question.newで空のインスタンスを作成しています。
「空のインスタンスを作成って何?」と思った方もいるはず。
そのためすこし、Question.newの処理について説明します。
ターミナルに下記のコマンドを入力してください。
rails c -s
railsコンソールが立ち上がります。
railsコンソールでどのような処理が行われているか見てみましょう。
※railsコンソールとは…Rubyのコードを動かすことができるツール
たとえば次のコマンド Question.new(title: “aaa”, body: “bbb”) を入力すると…
(少し分かりにくいので、ここはスクショを使って説明)
(このコマンドはコピペすると上手く動かないようなので、コピペせずに入力してください)
以下のような表示があると思います。
titleが”aaa”、bodyが”bbb”のインスタンスが作られました。
次は(title: “aaa”)のような値を渡さず、Question.newとだけ書いてみました。
すると空のインスタンスが作成されます。
つまりquestionsコントローラーのnewアクションでは、空のインスタンスを作り、@questionという変数に代入しています。
なぜこのような変数を作ったのか?
答えはビューファイルを作成すれば分かります。
(railsコンソールは「exit」を入力すれば終了できます。終了しておきましょう。)
app/views/questions/new.html.erbを作成して、下記のコードを書いてください。
質問の新規投稿フォームを作成しています。
<%= form_with(model: @question, local: true) do |f| %>
<div>
<%= f.text_field :title %>
</div>
<div>
<%= f.text_area :body %>
</div>
<%= f.submit %>
<% end %>
何か見慣れないコードが出てきましたね。
railsはフォームを簡単に作れるように、form_withというヘルパーを用意しています。
※ヘルパーとは?…viewをシンプルに書けるように、処理をまとめたものです。
form_withのあとに、コントローラーのnewアクションで作った@questionを渡しています。
@questionには、Question.newで作成された空のインスタンスが入っていますね?
form_withは物凄く賢いので、「空のインスタンスってことは、新規作成したいのかな?」と判断してくれます。
(後ほど解説しますが、@questionに入っているのが空のインスタンスじゃない場合は、編集投稿フォームだと判断してくれます)
つまりQuestion.newで作成した空のインスタンスが入っている@questionを渡すことで、このフォームは質問の新規投稿フォームだと指定しています。
続いてそれ以外のコードも見ていきましょう。
<%= f.text_field :title %>は結果的に、下記のHTMLコードを生成します。
<input type="text" name="question[title]" id="question_title">
これでユーザーにタイトルを入力してもらうことができます。
<%= f.text_area :body%>は、下記のHTMLコードを生成します。
<textarea name="question[body]" id="question_body"></textarea>
text_fieldで作成されるフォームだと一行でしか入力できませんが、text_areaなら複数行で入力できるフォームを作れます。
次にフォームから送られてきた値を、データベースに保存できるようにしましょう。
config/routes.rbに下記のコードを追加してください。
Rails.application.routes.draw do
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
get "/questions", to: "questions#index"
get "/questions/new", to: "questions#new"
post "/questions", to: "questions#create"
end
フォームで入力された値は、questionsコントローラーのcreateアクションで処理します。
それではquestionsコントローラーにcreateアクションを記述していきましょう。
class QuestionsController < ApplicationController
def index
@test = "テストテキスト"
end
def new
@question = Question.new
end
def create
@question = Question.new(question_params)
if @question.save
redirect_to("/questions/new")
else
render("questions/new")
end
end
private
def question_params
params.require(:question).permit(:title, :body)
end
end
また訳の分からんコードがたくさん…
ひとつひとつ理解していきましょう!
まず20行目にあるコードに注目。
def question_params
params.require(:question).permit(:title, :body)
end
Railsにはストロングパラメータという仕組みがあります。
セキュリティを強固にするために、指定されたパラメータのみ受け付ける仕組みです。
※パラメータとは…フォームなどから送られてきた値だと考えてください。
params.require(:question).permit(:title, :body)と記述することで、titleとbodyの値のみを受け付けることができます。
もし仮に、params.require(:question).permit(:title)と記述すると、bodyの値を受け取ることはできません。
フォームを改変されて、値を送信されると、こちらが意図しない値が送られることもあります。
そのためストロングパラメータで、こちらが指定した値のみ受け取るよう指定します。
次に、def question_paramsの上にあるprivateとは何か?
privateメソッド以下に書かれたコードは、このコントローラー内でしか使えません。
question_paramsは、このコントローラーでしか使わないのでprivate以下に記述しています。
あまり難しく考えず、ストロングパラメータを書くときは、そういうもんだと思ってください。
次は11行目に書かれているコードに注目してください。
@question = Question.new(question_params)
question_paramsで受け取る値を指定しましたね。
Question.new(question_params)でフォームから送られた値を使ってインスタンスを作り、@questionに代入します。
この時点ではまだデータベースに反映されていません。
@question.saveと書くことで、データベースに保存されます。
createアクションの目的は、データベースにデータを保存することです。
何かのビューファイルをユーザーに渡すことではありません。
そのため別にビューファイルは必要ありません。
とはいえこのままでは、次にどのような処理を行えばいいか分かりません。
そこで@question.saveが終わった後は、redirect_toを書き、どのURLに移動するか指定しましょう。
今回は質問の新規作成ページに戻らせます。
redirect_toのあとに、移動して欲しいURLを書けばいいだけです。
redirect_to("/questions/new")
こうすることで正常にデータベースに保存が行われた場合、新規作成のページに移動します。
しかしこれは正常にデータベースに保存が行われた場合の話です。
保存が失敗することもあります。
そのためif文で条件分岐させて、正常に保存できた場合の処理と、保存に失敗した場合の処理を書いています。
if @question.save
redirect_to("/questions/new")
else
render("questions/new")
end
とはいえ保存が失敗する場合って、どのような原因が考えられるのでしょうか?
一つの例としてバリデーションが考えられます。
バリデーションとは…保存されるデータを、本当に保存していいか検証すること
実際にバリデーションを書いてみましょう。
app/models/question.rbを開いて、下記のコードを追加してください。
class Question < ApplicationRecord
validates :title, presence: true, length: { maximum: 100 }
validates :body, length: { maximum: 3000 }
end
presence: trueと記述することで、titleを必須入力項目にできます。
そのためtitleに何も入力せずフォームの保存ボタンを押すと、保存が失敗します。
length:は文字数を制限する記述で、length: { maximum: 100 }と書くことで、101文字以上書くと、保存に失敗します。
このような保存に失敗した場合の処理を、else以下に記述しています。
render("questions/new")
render “questions/new”と書くことで、views/questions/new.html.erbファイルを、画面に表示することができます。
一度、保存に失敗した場合どうなるか見たいのですが…
このままでは「保存に失敗しました!」などのメッセージが出ないので、とても分かりにくいです。
そこでflashを使って、とりあえず簡易的にメッセージを表示させます。
class QuestionsController < ApplicationController
def index
@test = "テストテキスト"
end
def new
@question = Question.new
end
def create
@question = Question.new(question_params)
if @question.save
flash[:notice] = "成功!"
redirect_to("/questions/new")
else
flash.now[:alert] = "失敗!"
render("questions/new")
end
end
private
def question_params
params.require(:question).permit(:title, :body)
end
end
redirect_toのときはflashを使い、renderのときはflash.nowを使います。
次にapp/views/layouts/application.html.erbの<body>タグの下に、コードを追加します。
<!DOCTYPE html>
<html>
<head>
<title>BeginnerApp</title>
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
</head>
<body>
<p><%= notice %></p>
<p><%= alert %></p>
<%= yield %>
</body>
</html>
これだけで簡易的にですが、メッセージを表示することができます。
ブラウザを開いて「localhost:3000/questions/new」にアクセスして、titleのところを何も入力せず、bodyにだけ値を書いて、送信ボタンをクリックしてください。
(一度、ブラウザの更新ボタンを押してからにしてくださいね)
ちゃんと「失敗!」と表示されましたね。
ここでredirect_toとrenderの違いって何?と思った方。
しっかり考えながら読んでいる証拠です。
めちゃくちゃ勉強が上手いです。
最高です。
いや、マジで。
まずredirect_toの後に記述するのは、URLです。
renderの後に記述するのは、ビューのファイル名です。
redirect_toだと、新しいリクエストが発行されます。
つまりルーティング→コントローラー→ビューといういつもの流れで、ユーザーにページを返します。
renderはビューのファイルを呼ぶだけで、ルーティングにいって、コントローラーにいって…という処理がありません。
いまいちピンッとこないと思うので、実際にredirect_toが行われた場合の処理と、renderが行われた場合の処理を、見比べてみましょう。
app/controllers/questions_controller.rbの、newアクションとcreateアクションにコードを追加してください。
class QuestionsController < ApplicationController
def index
@test = "テストテキスト"
end
def new
@question = Question.new
@test = "new_テストテキスト"
end
def create
@question = Question.new(question_params)
@test = "create_テストテキスト"
if @question.save
flash[:notice] = "成功!"
redirect_to("/questions/new")
else
flash.now[:alert] = "失敗!"
render("questions/new")
end
end
private
def question_params
params.require(:question).permit(:title, :body)
end
end
この@testは処理の違いを見るための、ちょっとした目印として使います。
次はapp/views/questions/new.html.erbに、コードを追加してください。
<%= form_with(model: @question, local: true) do |f| %>
<div>
<%= f.text_field :title %>
</div>
<div>
<%= f.text_area :body %>
</div>
<%= f.submit %>
<% end %>
<div>
<%= @test %>
</div>
ブラウザを開いて、「localhost:3000/questions/new」にアクセスしてください。
<%= @test %>の部分は展開されて、”new_テストテキスト”と表示されていますね。
まずは保存に成功するケースを見てみましょう。
titleとbodyに何か適当な値を入力してください。
送信ボタンをクリックすると、保存に成功します。
このときの処理は下記のようになります。
questionsコントローラーのcreateアクションが実行される
↓
保存に成功!
↓
redirect_to(“/questions/new”)を実行して、URL「/questions/new」にアクセスする
↓
URL「/questions/new」にアクセスがあると、questionsコントローラーのnewアクションが実行される
↓
newアクションがapp/views/questions/new.html.erbをユーザーに返す
今までの知識を活かせば、特に問題なく理解できると思います。
次は保存に失敗するケースを見てみましょう。
titleには何も入力せず、bodyには何か適当な値を入力してください。
送信ボタンをクリックすると、保存に失敗します。
このときの処理は下記のようになります。
questionsコントローラーのcreateアクションが実行される
↓
保存に失敗!
↓
render(“questions/new”)を実行して、app/views/questions/new.html.erbをユーザーに返す
そして注目してほしいのが、<%= @test %>の部分です。
保存に成功した(redirect_toされた)ときは、”new_テストテキスト”と表示されていましたが、保存に失敗した(renderされた)ときは、”create_テストテキスト”と表示されていますね?
redirect_toだと新しいリクエストが発行されて、newアクションで定義した@testが使われています。
しかしrenderは新しいリクエストを発行していません。
createアクションにいる状態で、無理やりapp/views/questions/new.html.erbを呼び出しています。
createアクションにいるので、newアクションで定義している@testは使えません。
そのためrenderで呼び出したapp/views/questions/new.html.erbには、createアクションで定義した@testを渡しています。
何となく理屈は分かったかもしれませんが、なぜ保存に失敗した場合はrenderを使うのか?
もし仮に保存に失敗した場合もredirect_toを使うと、今まで入力した値が真っさらになります。
(newアクションで定義されている、空のインスタンスが入った@questionを使うため)
しかしrenderを使うと、保存に失敗した場合、入力した値を保持してページを返すことができます。
(createアクションで定義されている、フォームから送信された値が入った@questionを使うため)
試しにtitleに何も入れず、bodyに「ddd」と入力して、送信ボタンをクリックします。
失敗しても「ddd」が残ったままになっています。
保存に失敗した時、もし長文を入力していた場合、また一から入力するのは手間ですよね。
そのためユーザーの利便性を考えた結果、保存に失敗した場合の処理はrenderを使っています。
質問を表示できる機能を作ろう
作成した質問を表示する機能を作ります。
まずはconfig/routes.rbに下記のコードを追加しましょう。
Rails.application.routes.draw do
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
get "/questions", to: "questions#index"
get "/questions/new", to: "questions#new"
post "/questions", to: "questions#create"
get "/questions/:id", to: "questions#show"
end
次にデータベースから、データを取得する方法について見てみます。
railsコンソールで確認してみましょう。
rails c -s
Question.find(1)
Question.find(1)と入力することで、Questionsテーブルに入っている、idが1のレコードを取得できます。
※レコードとは…テーブルの「行(横軸)」のこと
idは重複することがありません。
そのため次に作られた質問のidは2になります。
つまりfindメソッドを使ってidを指定すれば、見たいレコードを取得できます。
(「exit」を入力してrailsコンソールを終了しておきましょう。)
次はquestionsコントローラーにshowアクションを作りましょう。
class QuestionsController < ApplicationController
def index
@test = "テストテキスト"
end
def show
@question = Question.find(1)
end
def new
@question = Question.new
@test = "new_テストテキスト"
end
def create
@question = Question.new(question_params)
@test = "create_テストテキスト"
if @question.save
flash[:notice] = "成功!"
redirect_to("/questions/new")
else
flash.now[:alert] = "失敗!"
render("questions/new")
end
end
private
def question_params
params.require(:question).permit(:title, :body)
end
end
うーん…
これではidが1の質問しか取得できません。
どうするか?
ユーザーに表示させたい質問のidを指定してもらって、そのidの質問を返せるようにします。
たとえばユーザーがid 1のレコードを見たいと思ったとき、URLはlocalhost:3000/questions/1と指定してもらいます。
つまり今回定義したURL ‘/questions/:id’の:id部分には、表示させたい質問のidを入れると考えてください。
このlocalhost:3000/questions/1の、「1」をコントローラーで取得します。
どうやって取得するのか?
下記のようにコードを書いてください。
class QuestionsController < ApplicationController
def index
@test = "テストテキスト"
end
def show
@question = Question.find(params[:id])
end
def new
@question = Question.new
@test = "new_テストテキスト"
end
def create
@question = Question.new(question_params)
@test = "create_テストテキスト"
if @question.save
flash[:notice] = "成功!"
redirect_to("/questions/new")
else
flash.now[:alert] = "失敗!"
render("questions/new")
end
end
private
def question_params
params.require(:question).permit(:title, :body)
end
end
ルーティングを定義するとき、get ‘/questions/:id’と記述しましたよね?
このように書くと、localhost:3000/questions/1の1には、:idというキーが紐づいています。
こんな感じ。
{“id” => “1”}
そして{“id” => “1”}から”1″を取り出すには、paramsを使います。
params[:id]と書くと、1が取り出されます。
※ここらへんの処理がピンッとこない方は、プロゲートでRubyを復習するといいかもしれません。
idが2の質問を見たいと思って、localhost:3000/questions/2にアクセスした場合はどうなるか?
{“id” => “2”}となっているので、paramsを使って”2″を取り出します。
つまり@question = Question.find(params[:id])というコードは、最終的に@question = Question.find(2)という意味を持ったコードになります。
※今回はまだ質問を1つしか作っていないので、viewファイルを作った後に、localhost:3000/questions/2にアクセスしてもエラーが表示されるだけです。
それではルーティングとコントローラーを書いたので、次はビューファイルを作成しましょう。
app/views/questionsフォルダに、show.html.erbというファイルを作成してください。
<p><%= @question.title %></p>
<p><%= @question.body %></p>
それではブラウザを開いて、「http://localhost:3000/questions/1」にアクセスしてみましょう。
作成した質問のtitleとbodyが表示されています。
作成した質問を表示できるようになりました!
デザインを整えたり、コードを整えたりしよう
デザインを少し整えていきます。
app/views/layouts/application.html.erbにある、<%= yield %>をdivで囲って、class=”container”をつけましょう。
<!DOCTYPE html>
<html>
<head>
<title>BeginnerApp</title>
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
</head>
<body>
<p><%= notice %></p>
<p><%= alert %></p>
<div class="container">
<%= yield %>
</div>
</body>
</html>
次はcssを書きます。
app/assets/stylesheets/application.cssを開いてください。
コメントがたくさんあるので、その下にコードを書いてください。
/* コメントがたくさん */
.container {
width: 80%;
margin: 20px auto;
}
input, textarea {
box-sizing: border-box;
width: 400px;
padding: 6px;
}
input[type="submit"] {
background-color: #FF5D57;
border-radius: 5px;
color: white;
padding: 10px;
text-align: center;
width: 150px;
}
textarea {
height: 120px;
}
HTMLやCSSに関してどのような処理をしているか分からない方は、プロゲートで復習してくださいね。
次はフォームにラベルをつけてあげましょう。
<%= form_with(model: @question, local: true) do |f| %>
<div>
<%= f.label :title, "タイトル" %><br>
<%= f.text_field :title %>
</div>
<div>
<%= f.label :body, "本文" %><br>
<%= f.text_area :body %>
</div>
<%= f.submit %>
<% end %>
<div>
<%= @test %>
</div>
12~14行目に書いているコードは、もう要らないので削除しておきましょう。
質問の新規投稿フォームは、このようになりました。
app/controllers/questions_controller.rbの12行目と17行目書いている、@test = “new_テストテキスト”と@test = “create_テストテキスト”も削除してください。
あとcreateアクションのredirect_toのURLを変更します。
今までは新規作成フォームのページにとばしていましたが、せっかく作成したなら、作成した質問の詳細ページにとびたいですよね。
そこで redirect_to(“/questions/#{@question.id}”) というコードに書き換えます。
#{@question.id}の中には、作成した質問のidが入ります。
class QuestionsController < ApplicationController
def index
@test = "テストテキスト"
end
def show
@question = Question.find(params[:id])
end
def new
@question = Question.new
end
def create
@question = Question.new(question_params)
if @question.save
flash[:notice] = "成功!"
redirect_to("/questions/#{@question.id}")
else
flash.now[:alert] = "失敗!"
render("questions/new")
end
end
private
def question_params
params.require(:question).permit(:title, :body)
end
end
最後に「localhost:3000」にアクセスしたとき、今までは初期画面を表示させていましたが、これからはapp/views/questions/index.html.erbを表示させます。
config/routes.rbに下記のコードを追加してください。
Rails.application.routes.draw do
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
root to: 'questions#index'
get "/questions", to: "questions#index"
get "/questions/new", to: "questions#new"
post "/questions", to: "questions#create"
get "/questions/:id", to: "questions#show"
end
実際にブラウザを開いて「localhost:3000」にアクセスしてください。
app/views/questions/index.html.erbが表示されていますね。
Railsビギナー 第1章「質問投稿機能を作ろう」まとめ
お疲れ様でした!
第1章終了です。
休憩がてらに、ぜひ下記の記事でも見てください。
ドン底から這い上がる過程を見れたり、フリーランスのリアルが分かったりするのでおすすめですよ↓
僕が新卒で入社した会社は、出版業界最大手の超ホワイト企業でした。 けれども僕はうつ病になりました。 そしてうつ病になった僕は、独学でフリーランスになりました。 ※自己紹介noteです。 ※フリーランスになって辛かった経験もリアルに書くので、ぜひ参考にしてください。 自己紹介 どうも、真木 裕也です! 僕は現在、フリーランスのwebマーケッター・プログラマーとして働いています。 しかしながらwebマーケティング会社や、webアプリ開発会社で働いたことはありません。 独学でマーケティングとプログラミングを学び、いきなりフリーランスになりました。 【名前】 真木
第2章ではユーザーのログイン・新規登録機能を、deviseというgemを使って作成します。
せっかく始めたのなら、ぜひ最後の第3章まで完走してくださいね!
大好評!公式LINE!独学でフリーランスになった
リアルなノウハウを発信!
これだけ豪華なノウハウが無料…?
IT・AI・マーケティングのリアルなコツや裏ワザを公式LINEで発信中!
知っておくと初心者でも仕事獲得に繋がるツールなど、フリーランスや副業に興味がある方は要チェックの内容です!
さらに今なら下記の豪華プレゼントをゲットできます!