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?

More than 5 years have passed since last update.

[memo]ActiveHash

Last updated at Posted at 2021-01-24

ActiveHash の使い方 まとめ

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

ActiveHash導入方法

Gemfileを編集

Gemfile
gem 'active_hash'

記述したらbundle installを実行

例 ArticleモデルでActiveHashを導入

記事を管理するArticleモデル
記事のジャンルを管理するGenreモデル
記事のジャンルは変更されないデータ=ActiveHashを用いて管理

①それぞれのモデルを作成
rails g model article
rails g model genre --skip-migration

--skip-migrationとは??
モデルファイルを作成するときに、マイグレーションファイルの生成を行わないためのオプション。今回、記事のジャンルの情報はデータベースに保存しない=マイグレーションファイルを作成する必要はない。

②genreモデルでクラスを定義し、ActiveHash::Base を継承するための記述を行う

ジャンルのデータは、配列にハッシュ形式で格納

models/genre.rb
class Genre < ActiveHash::Base
 self.data = [
   { id: 1, name: '--' },
   { id: 2, name: '経済' },
   { id: 3, name: '政治' },
   { id: 4, name: '地域' },
   { id: 5, name: '国際' },
   { id: 6, name: 'IT' },
   { id: 7, name: 'エンタメ' },
   { id: 8, name: 'スポーツ' },
   { id: 9, name: 'グルメ' },
   { id: 10, name: 'その他' }
 ]
 end
③①で生成されたarticleのマイグレーションファイルを編集・マイグレートする

以下の様に編集し ⇨  rails db:migrate
Articlesテーブルの中にgenre_idという名前のカラムを作成しているのは、投稿した記事を表示する際に、その記事に紐付いたジャンルを取得するため
Articleテーブルの中で、Genreモデル(ActiveHash)のidを外部キーとして管理することで、その記事に紐付いたジャンルの取得が実現

db/migrate/20XXXXXXXXXXXX_create_articles.rb
class CreateArticles < ActiveRecord::Migration[6.0]
 def change
   create_table :articles do |t|
     t.string     :title        , null: false
     t.text       :text         , null: false
     t.integer    :genre_id     , null: false
     t.timestamps
   end
 end
end
④モデル間でのアソシエーションの設定

ActiveHashを用いてアソシエーションを設定する場合は、ActiveHashで定義されているmoduleをモデルに取り込む必要がある。

1)ActiveHashを導入したい(される)モデル
投稿する記事=Articleは、1つのジャンル=Genreに紐付いています。そのため、Articleモデルにbelongs_toを設定します。
ActiveHashを用いて、belongs_toを設定するには、
extend ActiveHash::Associations::ActiveRecordExtensionsと記述してmoduleを取り込みます。

app/models/article.rb
class Article < ApplicationRecord
  extend ActiveHash::Associations::ActiveRecordExtensions
  belongs_to :genre
end

2)ActiveHashを設定したモデル
1つのジャンル=Genreは、たくさんの投稿物=Articlesに紐付いています。そのため、Genreモデルにはhas_manyを設定します。

ActiveHashを用いて、has_manyを設定するには、
include ActiveHash::Associationsと記述してmoduleを取り込みます。

app/models/genre.rb
class Genre < ActiveHash::Base
 self.data = [
   { id: 1, name: '--' },
  〜〜〜省略〜〜〜
   { id: 10, name: 'その他' }
 ]

  include ActiveHash::Associations
  has_many :articles

 end

※moduleとは、特定の役割を持つメソッドや定数に名前を付けてまとめたもの。どのようなmoduleが定義されているかは、こちらのリファレンスで確認。

※ActiveHashを用いたアソシエーションの設定は、他にもあります。詳しくはこちらのドキュメントを確認。

⑤バリデーションを設定

データベースに空の投稿が保存されないようにする場合、バリデーションヘルパーのnumericality(数値かどうかを検証する)を用いる。数値であればデータベースに保存を許可して、それ以外では保存が許可されないようにできます。今回においては、--を保存されないようにしたいので、id: 1以外であれば保存できるように設定すると

app/models/article.rb
class Article < ApplicationRecord
  extend ActiveHash::Associations::ActiveRecordExtensions
  belongs_to :genre

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

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

このバリデーションは、genre_idのid:1以外のときに保存できるという意味になる。

導入については以上です。ジャンル選択のプルダウン生成などはview関連になるため
別記事に追記予定。

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?