この記事では、HTMLタグ(SELECT/OPTION)を作成するためのテーブルをマイグレーション し、ビューで使用する方法を考えてきます。
さらに、cocoon で管理する方法も考えます。
テーブル構造を考える
他の(マシンの)システムで多いのは、コードテーブル、名称テーブルの類を利用する
一般論として、顧客マスターや商品マスター、社員マスターといったマスターでは、顧客マスターや商品コード、社員番号といったユニークキー(プライマリーキー)と、顧客名、商品名、社員名といった名称、さらに住所や販売価格、在庫数といった付随する情報がセットされていると思います。
どんなシステムでもコード値の存在チェックは行いますので、それを利用して、名称を表示しています。
そういったマスター以外に、細かい区分やフラグといったものに名称をつけたいといったニーズがあり(例えば、商品でしたら、1=仕入 商品、2=委託商品など)、一般的には、これを名称テーブルあるいはコードテーブルといったファイル名で取り扱うケースが多々あります。
もし、これがすでに基幹システムなどに存在し、夜間バッチ等でRails 用のデータベースに差し替えるようなことが可能ならば、それを利用してSELECTのOPTIONタグの表示名称として利用したいのですよね。
コードテーブルのデータ構造について
多くのケースでは、
コードヘッダー:コードキー(ユニークキー)と、このコードの名称や使用目的等を記述
コード明細:コードキー(ユニークキー)と実際の区分値とその名称や略称を保持
といった親子関係で表現されていることが多いと思います。
画面に表示される桁数には制限があるので、多くの場合は略称を持っています。
もし、Rails でこれをインポートするには、以下の構造になるはずです。
コードヘッダー:id とコードキー(ユニークキー)と、このコードの名称や使用目的等を記述
コード明細:*idと、ヘッダーテーブルのid**、実際の区分値とその名称や略称を保持
Rails のプライマリーキーはidになりますので、子にはヘッダーテーブルのid を持つことで、親子関係を実現します。
上記例では、子にはコードキー(ユニークキー)は持たないようにしていますが、Activerecord あるいはSQL の条件として持っても良いかと思います。
こちらをもとにして実装していくことにします。
(参考)夜間バッチで差し替えるには?
参考までに、ロジックを考えてみます。
プログラムその1:コードキー(ユニークキー)が期間。Rails 両者に存在する場合
親テーブルをUPDATEし、子のテーブルをDELETE/INSERTします。
その際、親のidを子にセットします。
プログラムその2:コードキー(ユニークキー)がRails 側に存在しない場合
親テーブルをINSERTし、子のテーブルをINSERTします。
親テーブルのidは新規に与えられますので、コードキー(ユニークキー)で親のidにを取得し、その親idも含めた形で子をINSERTしてください。
プログラムその3:コードキー(ユニークキー)がRails 側にのみ存在する場合
基幹側が削除されたとみなし、親テーブルをDELETEし、子のテーブルもDELETEします。
基幹側以外のデータも管理(入力)したい場合は、別のテーブルを用意したほうが賢明かもしれません。
実装手順
親子のテーブル作成
まずは親のテーブルを作成します。
bundle exec rails g scaffold Codeheader code_key:string code_name:string
code_keyは基幹システムのプライマリーキー、code_nameはこのコード自体の名称を記述します。
のちほど、cocoon でメンテナンス画面を作成するために、g scaffold
にしておきます。
次に、このテーブルを作成します。
bundle exec rails g model Codedetail value_key:string value_name:string short_name:string codeheader:belongs_to
value _keyは区分やフラグの値、value _nameはその名称、short_nameはその略称です。
codeheader:belongs_to
で親テーブルのidをセットするカラムが作成されます(MySQL ではid同様bigintとなる)。
こちらはscaffoldではなくg model
にしておきます。
モデルに追記する
app/models/codeheader.rb
に以下を追記します。
has_many :codedetails , dependent : :destroy
accepts_nested_attributes_for :codedetails , allow_destroy : true
reject_if: :all_blank
は親のみ作成される危険性があるため、記述を除去します。
app/models/codedetail.rb
に以下を追記します。
belongs_to :codeheader
ヘルパーにSELECT/OPTION用の配列を求める関数を作成
app/helpers/application_helper.rb
に以下を追記します。
def get_select_option (key)
return Codedetail .joins(:codeheader ).select(" codeheaders.*, codedetails.* " ).where(" codeheaders.code_key = ? " ,key)
end
ビュー側でヘルパーの関数を埋め込む
_form.html.haml
に以下を追記します(追記例)。
.field.col-md-4 .mb-3
= f.label :category , class : " form-label "
= f.collection_select :category , get_select_option(' category ' ), :value_key , :value_name , {prompt : " 選択してください " }, :class => ' form-control ' , :id => ' category '
上記はcategoryというコードキーを持つ一覧を取得してOPTIONタグを生成していきます。
value_name
をshort_name
に変更すると、略称がセットされると思います。
かなり簡単に実装できましたね。
cocoon を使って、メンテンス画面を作成する
基幹からデータ持ってくるだけでしたら、別段必要はないですが、基幹もなく、イチから用意したい場合は、cocoon を利用した管理画面を用意したほうが良いかと思います。
幸い、cocoon についてのコラムは用意していますが、それをリンクしながら、異なる点などを説明します。
inuinu-tech.hatenablog.jp
「modelおよびscaffoldの作成 」はこの記事のものを使用してください。
それ以降もProject、project、projectsはCodeheader、codeheader、codeheadersに差し替えてください。
同様に、Task、task、tsaksはCodedetail、codedetail、codedetailsに差し替えてください。
「コントローラーの変更 」のパラメータは下記のように変更してください。
●app/helpers/application_helper.rb
def codeheader_params
params.require(:codeheader ).permit(:code_key , :code_name , codedetails_attributes : [:id , :value_key , :value_name , :short_name , :_destroy ])
end
inuinu-tech.hatenablog.jp
tasksはcodedetailsに差し替えます。
inuinu-tech.hatenablog.jp
Task、task、tsaksはCodedetail、codedetail、codedetailsに差し替えてください。
inuinu-tech.hatenablog.jp
子の二重登録 エラーは、前出のapp/helpers/application_helper.rb
のパラメータ変更が行われているのならば、発生しないはずです。
子の0行エラー抑制
inuinu-tech.hatenablog.jp
Project、project、projectsはCodeheader、codeheader、codeheadersに差し替えてください。
同様に、Task、task、tsaksはCodedetail、codedetail、codedetailsに差し替えてください。
子の件数抑制
inuinu-tech.hatenablog.jp
inuinu-tech.hatenablog.jp
Project、project、projectsはCodeheader、codeheader、codeheadersに差し替えてください。
同様に、Task、task、tsaksはCodedetail、codedetail、codedetailsに差し替えてください。
(taskはTASKもありますね。)
行コピー
inuinu-tech.hatenablog.jp
inuinu-tech.hatenablog.jp
inuinu-tech.hatenablog.jp
taskのみcodedetailに読み替えてください。
inuinu-tech.hatenablog.jp
projectをcodeheaderに差し替えてください。
同様に、tsaksはcodedetailsに差し替えてください。
以上で、cocoon 化は完了するかと思います。
お好みで
お好みで、ページネーションや検索、ソートを実装してみてください。
inuinu-tech.hatenablog.jp
inuinu-tech.hatenablog.jp
時間があれば、日本語化も。
inuinu-tech.hatenablog.jp
これで、ほぼほぼ良い感じになると思います。