はじめに
現在未経験からのエンジニアへの転職するため、日々学習を励んでいます。
知識整理のためアウトプットします!
間違った内容などあるかもしれませんがご容赦ください!
ActiveHashとは
一言でまとめると、「変更されないデータをデータベースに保存することなく取り扱うことができるgem」と理解してます!
例えば、都道府県一覧などは変更されないですよね?!
このようなデータを直接モデルに記入することで、データベースには保存せずともデータが取り扱えるgemです!
つまり、ActiveHashを用いることでActiverecordメソッドが使えるようになるんです!
導入方法
gem 'active_hash'
% bundle install
これで下準備は終わり。
モデルを作成する
今回は、料理投稿アプリを想定して、foodモデルと、costモデルを作成します。
class CreateFoods < ActiveRecord::Migration[6.0]
def change
create_table :foods do |t|
t.string :title, null: false
t.integer :cost_id, null: false
t.timestamps
end
end
end
ここで注意!
カラム名に_idをつけ、カラムの型はinteger型にしましょう!
class Cost < ActiveHash::Base
self.data = [
{ id: 1, name: '100円以下' },
{ id: 2, name: '300円前後' },
{ id: 3, name: '500円前後' },
{ id: 4, name: '1,000円前後' },
{ id: 5, name: '2,000円前後' },
{ id: 6, name: '3,000円前後' },
{ id: 7, name: '5,000円前後' },
{ id: 8, name: '10,000円前後' },
]
end
cost.rbはエディタから直接ファイルを作り上記の方に記述します。
まずは、モデルの「Costクラス」を定義し、ActiveHash::Baseクラスを継承します。
ActiveHash::Baseは、あるクラス内でActiveHashを用いる際に必要となるクラスです。
ActiveHash::Baseを継承することで、ActiveRecordメソッドを使用できるようになります。
##アソシエーションの設定
投稿した料理は、1つのコストに紐付いています。そのため、Foodモデルにはbelongs_toを設定します。
この際、extend ActiveHash::Associations::ActiveRecordExtensionsと記述してmoduleを取り込みます。
class Food < ApplicationRecord
extend ActiveHash::Associations::ActiveRecordExtensions
belongs_to :cost
end
1つのコストは、たくさんの投稿した料理に紐付いています。そのため、Genreモデルにはhas_manyを設定します。
この際、include ActiveHash::Associationsと記述してmoduleを取り込みます。
class Cost < ActiveHash::Base
self.data = [
{ id: 1, name: '100円以下' },
{ id: 2, name: '300円前後' },
{ id: 3, name: '500円前後' },
{ id: 4, name: '1,000円前後' },
{ id: 5, name: '2,000円前後' },
{ id: 6, name: '3,000円前後' },
{ id: 7, name: '5,000円前後' },
{ id: 8, name: '10,000円前後' },
]
include ActiveHash::Associations #ここを追加
has_many :foods #ここを追加
end
##collection_selectを用いてブルダウンメニューを表示させる。
<%= f.collection_select(:cost_id, Cost.all, :id, :name, {}, {class:"cost-select"}) %>
#各引数の役割
<%= form.collection_select(保存されるカラム名, オブジェクトの配列, カラムに保存される項目, 選択肢に表示されるカラム名, オプション, htmlオプション) %>
##バリデーションを設定しよう
今回は2パターン紹介します!
①「numericality」というバリデーション のヘルパーを使用する方法
numericalityとは、数値かどうかを検証するバリデーションの一種です。
数値であればデータベースに保存を許可して、それ以外では保存が許可されないようにできます。
class Cost < ActiveHash::Base
self.data = [
{ id: 1, name: '---' }, #id:1に「---」を追加する。
{ id: 2, name: '100円以下' },
{ id: 3, name: '300円前後' },
{ id: 4, name: '500円前後' },
{ id: 5, name: '1,000円前後' },
{ id: 6, name: '2,000円前後' },
{ id: 7, name: '3,000円前後' },
{ id: 8, name: '5,000円前後' },
{ id: 9, name: '10,000円前後' },
]
include ActiveHash::Associations
has_many :foods
end
class Food < ApplicationRecord
extend ActiveHash::Associations::ActiveRecordExtensions
belongs_to :cost
validates :title, presence: true
#コストの選択が「---」の時は保存できないようにする
validates :cost_id, numericality: { other_than: 1 }
end
###②collection_selectのオプションを使用する方法
collection_selectの第五引数で設定するオプションを使用します。
#第五引数に{ include_blank: "---" }を記入する。
<%= f.collection_select(:cost_id, Cost.all, :id, :name, { include_blank: "---" }, {class:"cost-select"}) %>
include_blankをしようすることで、値のない選択肢を先頭にすることができます。
そうすることで、、、with_optionsでまとめることができる!!
ちょっと見やすいかな?
class Food < ApplicationRecord
extend ActiveHash::Associations::ActiveRecordExtensions
belongs_to :cost
with_options presence: true do
validates :title
validates :cost_id
end
end
##終わりに
以上になります!
間違ってたら、バシバシ言っていただけるとありがたいです!