はじめに
Railsでプログラミングを学習し始めた方向けの記事になります。
自分の復習も兼ねて、できるだけわかりやすく記事を書いていきたいと思います!
環境
Rails ver8.1.2
Dockerを使用
Rails new済みの状態
(細かくコマンドを叩いていますが、省略できる方はしてください!)
セレクトボックスとは?
記載する選択肢が多い場合などに便利です!
実装手順
今回はレシピアプリの想定で作ります。
(作成するものに応じてファイル名は変えてください。)
1.セレクトボックスの中身を作る
まずはセレクトボックスで映したい情報をDBに入れましょう!
db/seed
Food.create!([
{ name: "おにぎり" },
{ name: "サンドイッチ" },
{ name: "お弁当" }
])
こんな感じで表示したい情報を入れます。
コードの解説
Food.create!
-
Food: データを保存する対象のモデルクラスを指定しています。
-
create!:
createで先ほどのハッシュを保存する。 -
「!」の有無(重要):
-
create!(ビックリマークあり): 保存に失敗した際、例外(エラー)を発生させて処理を中断します。
-
create(ビックリマークなし): 失敗しても false を返すだけで処理が続いてしまいます。
Seedファイルでは「データが入っていないのに成功したと勘違いする」のを防ぐため、create! を使うのが鉄則です!
-
docker compose exec web rails db:seed
ターミナルで上記のコマンドを叩き、DBを更新しておきましょう!
2.Modelの作成
RecipeモデルとFoodモデルを作ります。
ターミナルで下記のコマンドを叩き作成します。
docker compose exec web rails g model Food name:string
docker compose exec web rails g model Recipe title:string food:references
(food:references と書くことで、自動的に food_id カラムが作られ、モデルに belongs_to :food が追記されます!)
次に各モデルの関係性を記述します。
# app/models/food.rb
class Food < ApplicationRecord
has_many :recipes
end
# app/models/recipe.rb
class Recipe < ApplicationRecord
belongs_to :food
end
-
「1つの食べ物は、たくさんのレシピに使われる(has_many)」
-
「1つのレシピは、特定の食べ物に属している(belongs_to)」
という親子関係をRailsに教えてあげています。
docker compose exec web rails db:migrate
モデルを作成・編集した後は、必ず以下のコマンドを叩いてデータベースに反映させましょう!
3.Controllerの作成
ターミナルで下記のコマンドを叩き、作成します。
docker compose exec web rails generate controller recipes
次に下記のように記述をします。
# app/controllers/recipes_controller.rb
class RecipesController < ApplicationController
def index
@recipe = Recipe.new
@food_options = Food.all.map { |f| [f.name, f.id] }
end
end
コードの解説
-
@recipe = Recipe.new:
form_with というフォーム作成機能を使う際、「これからどんなデータ(Recipe)を作るのか」という情報をRailsに教える必要があるための「空の入れ物」を作っています。 -
@food_options = Food.all.map { |f|[f.name, f.id] }: - セレクトボックスの選択肢として使うデータを、データベースから取得して加工しています。
- Food.all : 先ほど記述したdb/seedのFood内にあるデータをすべて取ってきます。
- .map: 取ってきたデータの塊を、一つずつ取り出して加工します。
(eachは元の配列をそのまま返しますが、mapは加工した結果を新しい配列として返してくれるため、セレクトボックス用の配列を作るのに適しています。) - [f.name, f.id]: セレクトボックスのルールである ["表示する名前", 保存するID] という配列の形に整えています。
4.Routes設定
次に最後に行うView作成の前にルーティングを設定しておきましょう!
# config/routes.rb
Rails.application.routes.draw do
resources :recipes, only: [:index]
end
これでindex画面のpathを作ります。
5.Viewの作成
ターミナルで下記のコマンドを叩き、ビューファイルを作成します。
touch app/views/recipes/index.html.erb
recipes/ディレクトリがない場合は、
mkdir app/views/recipes
で作成してからtouchでindexファイルを作成してください。
次に中身を記述します。
<%= form_with model: @recipe, local: true do |f| %>
<div>
<%= f.label :food_id, "食べ物" %>
<%= f.select :food_id, @food_options,
{ include_blank: "選択してください" },
{ class: "form-control" } %>
</div>
<% end %>
コード解説
-
<%= f.label :food_id, "食べ物" %>:
画面上に「食べ物」というラベルを表示します。 -
<%= f.select :food_id, @food_options, { include_blank: "選択してください" }, { class: "form-control" } %>:- :food_id: 保存先(Recipeモデル)のカラム名。
- @food_options: コントローラーで準備した、選択肢のデータ(配列)←先ほどのmap~~のところで作成しています。
- { include_blank: "選択してください" }: オプションの設定です。未選択の時に表示するテキストを指定します。
- { class: "form-control" }: HTMLとしての設定です。CSS(Bootstrapなど)を適用するためのクラス名を指定します。
6.完成!
こんな感じでセレクトボックスが作成できました!
味気ないのでTailWindなどCSSで加工してあげるといいですね!
まとめ
今回は、Railsで基本的なセレクトボックスを実装する方法を解説しました。
実装のポイントを振り返ると:
Model: 親子関係(1対多)を正しく定義する。
Seed: create! を使い、確実にデータを用意する。
Controller: mapを使い、ビューが扱いやすい形にデータを加工する。
View: 引数の順番に気をつけて f.select を記述する。
MVC(モデル・ビュー・コントローラー)がどう連携しているかの流れを意識すると、他の機能もグッと作りやすくなります!

