Globalid
irb(main):001:0> dog_gid = Dog.find(1).to_global_id
=> #<GlobalID:0x00007fa353e34588 @uri=#<URI::GID gid://global-id/Dog/1>>
irb(main):002:0> dog_gid.uri
=> #<URI::GID gid://global-id/Dog/1
irb(main):003:0> dog_gid.to_s
=> "gid://global-id/Dog/1"
irb(main):005:0> GlobalID::Locator.locate dog_gid
=> #<Dog id: 1, name: "ハスキー", created_at: "2019-07-06 23:59:43", updated_at: "2019-07-06 23:59:43">
セレクトボックスのグループ化
ポリモーフィックのデータ構造のセレクトボックスのグループ化(grouped_collection_select)に利用してみた
アウトプット(html)
<div class="field">
<select name="animal[global_target_id]" id="animal_global_target_id">
<optgroup label="Dog">
<option value="gid://global-id/Dog/1">ハスキー</option>
<option value="gid://global-id/Dog/2">ゴールデンレトリバー</option>
<option value="gid://global-id/Dog/3">コーギー</option>
</optgroup>
<optgroup label="Cat">
<option value="gid://global-id/Cat/1">雑種</option>
<option value="gid://global-id/Cat/2">スコティッシュ・フォールド</option>
<option value="gid://global-id/Cat/3">アメリカン・ショートヘア</option>
</optgroup>
</select>
</div>
実装
サンプル実装
- model
class Animal < ApplicationRecord
belongs_to :target, polymorphic: true
def global_target_id
self.target.to_global_id.to_s if target.present?
end
end
class Dog < ApplicationRecord
has_one :animal, as: :target
def global_id
self.to_global_id.to_s
end
class << self
def human_model_name
model_name.human
end
end
end
class Cat < ApplicationRecord
has_one :animal, as: :target
def global_id
self.to_global_id.to_s
end
class << self
def human_model_name
model_name.human
end
end
end
- view
<%= form_with(model: animal, local: true) do |form| %>
<div class="field">
<%= form.grouped_collection_select :global_target_id, [Dog, Cat], :all, :human_model_name, :global_id, :name, {}, {} %>
</div>
<div class="actions">
<%= form.submit %>
</div>
<% end %>
- controller
# POST /animals
# POST /animals.json
def create
@animal = Animal.new
@animal.target = GlobalID::Locator.locate animal_params[:global_target_id]
respond_to do |format|
if @animal.save
format.html { redirect_to @animal, notice: 'Animal was successfully created.' }
format.json { render :show, status: :created, location: @animal }
else
format.html { render :new }
format.json { render json: @animal.errors, status: :unprocessable_entity }
end
end
end