LoginSignup
1
1

More than 3 years have passed since last update.

データベースになくても、データとして扱える活動的なハッシュ

Posted at

はじめに

 アンケートなんかでよく見かける、都道府県をプルダウンから選択させる機能。、form_withメソッドを使用して投稿する機能をもたせることができる。しかし、その都道府県はテーブル上では数値で管理されている方が使い勝手がよい。数値で管理できるようにするには、予め、都道府県名とそれに紐づく数字を用意しておく必要がある。そのようなときに便利な機能が、ActiveHashである。

ActiveHashとは

 基本的に変更することのないデータをモデル内に記入することで、データベースへ保存せずにデータを取り扱うことができるようになるGem。主に、ビューで、プルダウンメニューとして表示させたいときに使う。

公式ドキュメントはこちら

準備の流れ

1. Gemの記述
2. Gemをインストール
3. モデルを生成

1. Gemの記述

ファイルのいちばん下の行でOK

Gemfile
gem 'active_hash'

2. Gemをインストール

% bundle install

3. モデルを生成

% rails g model モデル名 --skip-migration

モデル名には、プルダウンメニューを一括りにするような名前が望ましい。
ex)野球、サッカー、テニス…
        のようなプルダウンを作成する場合は、モデル名はsportとなる。

--skip-migrationオプションをつけることで、マイグレーションファイルを生成しなくなる。ActiveHashはデータベースに保存しないので、マイグレーションファイルを必要としない。

以後、スポーツのプルダウンメニューを例に説明する。

記述から表示までの流れ

4. クラスを定義し継承する
5. プルダウンメニューの項目を記述
6. アソシエーションを記述
7. バリデーションを記述
8. プルダウンメニューを表示

4. クラスを定義し継承する

「3. モデル生成」で作られたモデルを以下の記述に変更する。

app/models/sport.rb
class Sport < ActiveHash::Base
  self.data = []
end

ActiveHash::Baseを継承することで、ActiveRecordのメソッドが使用できる。

5. プルダウンメニューの項目を記述

プルダウンの中身は、配列にハッシュで入れる。

app/models/sport.rb
class Sport < ActiveHash::Base
  self.data = [
    { id: 1, name: '---' },
    { id: 2, name: 'Baseball' },
    { id: 3, name: 'Soccer' },
    { id: 4, name: 'Tennis' }
  ]
end

6. アソシエーションを記述

以下、すでに、別の投稿したものを保存するテーブルが存在する前提の説明。

app/models/post.rb
class Post < ApplicationRecord
  extend ActiveHash::Associations::ActiveRecordExtensions
    belongs_to_active_hash :sport
end

extend ActiveHash::Associations::ActiveRecordExtensionsの記述によって、belongs_to_active_hashメソッドが使えるようになる。

sportモデルにアソシエーションの記述の必要はない。

※通常のアソシエーションと記述が異なる点に注意

7. バリデーションを記述

app/models/post.rb
class Post < ApplicationRecord
  extend ActiveHash::Associations::ActiveRecordExtensions
    belongs_to_active_hash :sport

  validates :sport_id, presence: true #空の投稿を保存できない


  validates :sport_id, numericality: { other_than: 1 } 
                        #プルダウンの選択が「--」の時は保存できない
end

8. プルダウンメニューを表示

collection_selectメソッド


collection_select(保存されるカラム名, オブジェクトの配列, カラムに保存される項目, 選択肢に表示されるカラム名, オプション, htmlオプション)
collection_select(:sport_id, Sport.all, :id, :name, {}, {class:"sport-select"})

保存されるカラム名:テーブルのどのカラムに保存をするのか。
オブジェクトの配列:配列のハッシュ全て表示させる場合は、.allでOK
カラムに保存される項目:app/models/sport.rbの中で、id:としていた部分を、カラムに保存させたい
選択肢に表示されるカラム名:プルダウンでapp/models/sport.rbname:としていた部分を表示させる
オプション:必要に応じて
htmlオプション:クラス名など

最後に

 とにかく、collection_selectメソッドの引数が多すぎて、混乱しそう…

1
1
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
1
1