1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

active_hashについて

Posted at

active_hashとは

gemの一種でハッシュのデータを、ActiveRecordと同じように使えるようにしてくれる。
都道府県など基本的に変更されないデータはデータベースに保存する必要性がなく、ビューファイルにデータを直接書いてしまうと、可読性に欠けてしまう。このような場面でactive_hashを使う。

目標

簡単なActiveHashを使用したスポーツ記事の投稿アプリの作成(今回CSSは割愛)

ActiveHashを導入

gem 'active_hash'

モデルを作成する

次にモデルを作成する。
今回モデルはsportsモデルとgenreモデルの2つ作成する。
まずはrails g modelでsportsモデルを作成。

rails g model sports

次にgenreモデルを作成します。

rails g model genre --skip-migration

今回の--skip-migrationとは、モデルファイルを作成するときに、マイグレーションファイルの生成を行わないためのオプションです。

次にgenre.rbを編集していきます。
この時にActiveHash::Baseクラスを継承するようにします。ActiveHash::Baseを継承することで、ActiveRecordと同じようなメソッドを使用できるようになります。結果以下のようなオブジェクトを記述したとします。

class Genre < ActiveHash::Base
 self.data = [
   { id: 1, name: '--' },
   { id: 2, name: '野球' },
   { id: 3, name: 'サッカー' },
   { id: 4, name: 'テニス' },
   { id: 5, name: '卓球' },
   { id: 6, name: 'バスケットボール' },
   { id: 7, name: '陸上' },
   { id: 8, name: 'スポーツ' }
 ]
 end

ジャンルのデータは、配列にハッシュ形式で格納しています。

またsportsモデルのマイグレーションファイルにgenre_idというカラムを追加することによってsportsテーブルのなかでGenreモデル(ActiveHash)のidを外部キーとして管理することで、その記事に紐付いたジャンルの取得ができるようになります。

class CreateSports < ActiveRecord::Migration[6.0]
 def change
   create_table :sports do |t|
     t.string     :title        , null: false
     t.text       :text         , null: false
     t.integer    :genre_id     , null: false     t.timestamps
   end
 end
end
$ rails db:create
$ rails db:migrate

アソシエーションの設定

active_hashにはbelongs_to_active_hashメソッドが用意されているので、
sports.rbに このメソッドを記述し、アソシエーションを定義する。

class Sports < ApplicationRecord
  extend ActiveHash::Associations::ActiveRecordExtensions
  belongs_to :genre
end

バリデーションを設定

先ほどのsports.rbにバリデーションを追記する。

class Sports < ApplicationRecord
  extend ActiveHash::Associations::ActiveRecordExtensions
  belongs_to :genre

  #空の投稿を保存できないようにする
  validates :title, :text, presence: true

  #ジャンルの選択が「--」の時は保存できないようにする
  validates :genre_id, numericality: { other_than: 1 } 
end

ルーティングの設定

Rails.application.routes.draw do
  root to: 'sportses#index'
  resources :sportses
end

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

rails g controller sportses index new

コントローラーの編集

articles_controller.rb
class ArticlesController < ApplicationController
  def index
    @sportses = Sports
  end

  def new
  end

  def create
    @sports = Sports.new(sports_params)
    if @sports.save
      redirect_to root_path
    else
      render :new
    end
  end

  private

  def sports_params
    params.require(:sports).permit(:title,:text,:genre_id)
  end
end

ビューの編集

app/views/articles/index.html.erb
<h1>記事一覧</h1>
<%= link_to "投稿する", new_sports_path, class:"post" %>

<% @sportses.each do |sports| %>
  <div class="sports">
    <div class="sports-genre">
      <%= sports.genre.name %>
    </div>
    <div class="sports-title">
      <%= sports.title %>
    </div>
    <div class="sports-text">
      <%= sports.text %>
    </div>
  </div>
<% end %>

プルダウンバーの実装

記事投稿画面の実装です。

app/views/articles/new.html.erb
<%= form_with model: @sports, url:sportses_path, local: true do |f| %>
  <div class="sports-box">
    記事を投稿する
    <%= f.text_field :title, class:"title", placeholder:"タイトル" %>
    <%= f.text_area :text, class:"text", placeholder:"テキスト" %>
    <%= f.collection_select(:genre_id, Genre.all, :id, :name, {}, {class:"genre-select"}) %>
    <%= f.submit "投稿する" ,class:"btn" %>
  </div>
<% end %>

collection_selectを使うことで先ほどのアクティブハッシュをプルダウン形式で使用することができる。
collection_selectは第一引数から第五引数まで存在し以下の順に引数を入力していく。
Genre.allによってgenre.rbのデータ(配列)を指定している。ビューでユーザーが実際に選んだスポーツ名はgenre_idとしてsportsモデルに保存されるという流れになる。

<%= form.collection_select(保存されるカラム名, オブジェクトの配列, カラムに保存される項目, 選択肢に表示されるカラム名, オプション, htmlオプション) %>

<%= f.collection_select(:genre_id, Genre.all, :id, :name, {}, {class:"genre-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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?