LoginSignup
0
0

More than 1 year has passed since last update.

ActiveHashの導入目的とアプリ実装までの簡単な流れ

Last updated at Posted at 2021-01-16

※2022年から技術系の記事は個人ブログに投稿しております。ぜひこちらもご覧ください→yamaday0u Blog

ActiveHashとは

都道府県名などの変更されないデータをモデルファイル内に直接記述することで、データベースへ保存せずにデータを取り扱うことができるgemです。

ActiveHashを導入すれば、以下のようなプルダウンメニューを作成するときに大いに役立ちます。

スクリーンショット 2021-01-16 23.55.35.png

ActiveHashを導入する目的

ユーザー情報のような編集されることがあるデータと違って、都道府県名などは変更されないデータなので、データベースにわざわざ保存する必要がありません。

かといってビューファイルに直接都道府県名のプルダウンメニューを作ってしまうとコードが肥大化して可読性が下がってしまいます。

そこでActiveHashを使ってモデルからデータを呼び出すという方法を採ることでコードの管理がしやすくなります。

プルダウンメニューの実装

住んでいる都道府県を投稿するアプリを使って説明します。

以下のコマンドを入力してRailsアプリを作成します。

ターミナル
rails _6.0.0_ new activehash_app -d mysql
rails db:create

続いて、モデル、コントローラー、ビューを用意します。

モデルを作成

ターミナル
rails g model address      

上記コマンドで生成されたマイグレーションファイルにnameカラムとprefecture_idカラムを以下のとおり記述してマイグレートします。

prefecture_idカラムには、後でActiveHash gemで導入するプルダウンメニューの情報が入ります。

データ型がinteger型なのは、のちに作成するprefectureのデータをアソシエーションのようにidから引用するためです。

2021XXXXXXXXXX_create_addresses.rb
class CreateAddresses < ActiveRecord::Migration[6.0]
  def change
    create_table :addresses do |t|
      t.string :name, null: false
      t.integer :prefecture_id, null: false
      t.timestamps
    end
  end
end
ターミナル
rails db:migrate

コントローラーとビューを作成

下記のコマンドでコントローラーに加えて、一覧表示と新規投稿のビューをまとめて作成します。

ターミナル
rails g controller addresses index new

コントローラーとビュー(indexnew)を以下のように記述します。

app/controllers/addresses_controller.rb
class AddressesController < ApplicationController
  def index
    @addresses = Address.order("created_at DESC")
  end

  def new
    @address = Address.new
  end

  def create
    @address = Address.new(address_params)
    if @address.valid?
      @address.save
      return redirect_to root_path
    else
      render "new"
    end
  end

  private
  def address_params
    params.require(:address).permit(:name, :prefecture_id)
  end
end
app/views/addresses/index.html.erb
<h1>あなたの住んでいる都道府県は?</h1>
<%= link_to "投稿する", new_address_path %>
<div>
  <ul>
    <% if @addresses %>
      <% @addresses.each do |address| %>
      <li>
        <%= address.name %>
        <%= address.prefecture.name %>
      </li>
      <% end %>
    <% end %>
  </ul>
</div>

app/views/addresses/new.html.erb
<%= form_with model: @address, url:addresses_path, local: true do |f| %>
  <div class="article-box">
    あなたの名前と住んでいる都道府県を投稿する
    <div>
      <p><%= f.text_area :name, placeholder:"あなたの名前" %></p>
      <p><%= f.collection_select(:prefecture_id, Prefecture.all, :id, :name, {}, {class:"genre-select"}) %></p>
      <%= f.submit "投稿する" ,class:"btn" %>
    </div> 
  </div>
  <%= link_to "戻る", root_path %>
<% end %>

ActiveHashの導入

いよいよActiveHashを導入します。
Gemfileの一番下に下記の記述をして、ターミナルでbundle installします。

Gemfile
gem 'active_hash'
ターミナル
bundle install

都道府県のリストを用意するため、prefectureモデルを作成します。

ここで、いつものrails g model :モデル名コマンドに--skip-migrationというオプションを付けます。

--skip-migrationはマイグレーションファイルの作成をスキップしてくれるオプションです。都道府県に関する情報はデータベースに保存しないためです。

ターミナル
rails g model prefecture --skip-migration

作成したprefecture.rbに、以下のように記述します。

app/models/prefecture.rb
class Prefecture < ActiveHash::Base
  self.data = [
    {id: 0, name: '--'}, {id: 1, name: '北海道'}, {id: 2, name: '青森県'}, 
    {id: 3, name: '岩手県'}, {id: 4, name: '宮城県'}, {id: 5, name: '秋田県'}, 
    {id: 6, name: '山形県'}, {id: 7, name: '福島県'}, {id: 8, name: '茨城県'}, 
    {id: 9, name: '栃木県'}, {id: 10, name: '群馬県'}, {id: 11, name: '埼玉県'}, 
    {id: 12, name: '千葉県'}, {id: 13, name: '東京都'}, {id: 14, name: '神奈川県'}, 
    {id: 15, name: '新潟県'}, {id: 16, name: '富山県'}, {id: 17, name: '石川県'}, 
    {id: 18, name: '福井県'}, {id: 19, name: '山梨県'}, {id: 20, name: '長野県'}, 
    {id: 21, name: '岐阜県'}, {id: 22, name: '静岡県'}, {id: 23, name: '愛知県'}, 
    {id: 24, name: '三重県'}, {id: 25, name: '滋賀県'}, {id: 26, name: '京都府'}, 
    {id: 27, name: '大阪府'}, {id: 28, name: '兵庫県'}, {id: 29, name: '奈良県'}, 
    {id: 30, name: '和歌山県'}, {id: 31, name: '鳥取県'}, {id: 32, name: '島根県'}, 
    {id: 33, name: '岡山県'}, {id: 34, name: '広島県'}, {id: 35, name: '山口県'}, 
    {id: 36, name: '徳島県'}, {id: 37, name: '香川県'}, {id: 38, name: '愛媛県'}, 
    {id: 39, name: '高知県'}, {id: 40, name: '福岡県'}, {id: 41, name: '佐賀県'}, 
    {id: 42, name: '長崎県'}, {id: 43, name: '熊本県'}, {id: 44, name: '大分県'}, 
    {id: 45, name: '宮崎県'}, {id: 46, name: '鹿児島県'}, {id: 47, name: '沖縄県'}
  ]
  include ActiveHash::Associations #ActiveHashに定義されているモジュールを読み込み
  has_many :address #addressモデルとのアソシエーションを定義
end

都道府県のデータを配列にハッシュ形式で入れます。
また、include ActiveHash::AssociationsでActiveHashに定義されているモジュールを読み込み、has_manyを記述してAddressモデルとのアソシエーションを定義しています。

ActiveHashのモジュールについては公式GitHubのREADMEライブラリを参照してください。

address.rbにも同様に、モジュールを読み込み、belongs_toでPrefectureモデルとのアソシエーションを定義します。

app/models/address.rb
class Address < ApplicationRecord
  extend ActiveHash::Associations::ActiveRecordExtensions #Activehashに定義されているモジュールを読み込み
  belongs_to :prefecture #prefectureモデルとのアソシエーションを定義
end

上記のアソシエーションを定義することで、先ほど作成したindex.html.erbでPrefectureモデルに格納した都道府県名にアクセスできるようになりました。

app/views/addresses/index.html.erb(再掲)
<h1>あなたの住んでいる都道府県は?</h1>
<%= link_to "投稿する", new_address_path %>
<div>
  <ul>
    <% if @addresses %>
      <% @addresses.each do |address| %>
      <li>
        <%= address.name %>
        <%= address.prefecture.name %><%# アソシエーション定義によってprefecure.rbに格納している都道府県名にアクセスできる %>
      </li>
      <% end %>
    <% end %>
  </ul>
</div>

参考資料

ActiveHashの公式GitHub

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