ポリモーフィックなカラムのセレクトボックスを作る
rails4
ポリモーフィック(polymorphic)関連とは
UserモデルとPostモデルの両方にPhotoモデルを関連つけたい。
ユーザと記事は画像を持てる。みたいな時に
このポリモーフィック関連を使うといい感じに実装できる。(~ableにするのが慣習っぽい。)
使うには、Photoモデルに
photoable_type: string photoable_id: integer
みたいなカラムが必要で、Photoモデルには『 photoable 』という名前でポリモーフィックするよという宣言が必要になる。
ポリモーフィックなカラムのセレクトボックスを作る
本題。
Photo編集画面から、UserモデルとPostモデルのレコードをどちらに属するかを選べる画面にしてみる。
通常の1対1の関連なら、idだけわかればいいので
f.select_collection :hoge_id
と書けるけど、ポリモーフィックだと○×_typeに入れるモデル名が必要になるので、そのままのselect_collectionではできない。
どうするかというと、セレクトボックスを変更した時に、hiddenなfiledにしている×○able_typeをセットする。
# _form.html.erb @photoables = Hoge.all + Foo.all @photo = Photo.find(1) ------------ <%= f.select :photoable_id, options_for_select(@photoables.map{ |s| [s.name, s.id, { 'data-resource_model' => s.class, 'data-text' => s.name }]}, {}, { onchange: "setPhotoableType(this)" } %> <%= f.hidden_field :photoable_type, value: @photo.photoable_type %> <script> (function() { // セレクトボックスを選択中のもににフォーカスする var name = "<%= @photo.photoable.try(:name) %>"; $("#photo_ptohoable_id option[data-text=" + name + "]").attr('selected','selected'); })(); function setPhotoableType(select_input){ $("#photo_photoable_type").val($(select_input.options[select_input.selectedIndex]).data('resource_model')); } </script>
newアクションの時だと、これで問題ないんだけどeditアクションだとセレクトボックスが初期値になる。
たぶんf.selectって第一引数のカラムとoptionのvalueに一致するものにフォーカスを変えるんだけど、
valueに重複があるから初期値のままになってるっぽい。
ここは強引だけどonloadでセレクトボックスのフォーカスをかえている。