0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[Rails/初学者向け]セレクトボックスの作成

Posted at

はじめに

Railsでプログラミングを学習し始めた方向けの記事になります。
自分の復習も兼ねて、できるだけわかりやすく記事を書いていきたいと思います!

環境

Rails ver8.1.2
Dockerを使用
Rails new済みの状態
(細かくコマンドを叩いていますが、省略できる方はしてください!)

セレクトボックスとは?

スクリーンショット 2026-01-24 1.21.07.png
こういった選択肢を選ぶ箱のことですね!

記載する選択肢が多い場合などに便利です!

実装手順

今回はレシピアプリの想定で作ります。
(作成するものに応じてファイル名は変えてください。)

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.完成!

実際の動きはこちら↓
select.gif

こんな感じでセレクトボックスが作成できました!
味気ないのでTailWindなどCSSで加工してあげるといいですね!

まとめ

今回は、Railsで基本的なセレクトボックスを実装する方法を解説しました。

実装のポイントを振り返ると:
Model: 親子関係(1対多)を正しく定義する。
Seed: create! を使い、確実にデータを用意する。
Controller: mapを使い、ビューが扱いやすい形にデータを加工する。
View: 引数の順番に気をつけて f.select を記述する。
MVC(モデル・ビュー・コントローラー)がどう連携しているかの流れを意識すると、他の機能もグッと作りやすくなります!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?