これは、多形関連のややユニークなバージョンです。それは私が解決しようとしている苦労している多くの良い答えに出くわしていない "実世界"の問題の一つです。形式での多形関連のレンダリング
Transaction
レコードは多くがTasks
であり、各Task
はAssignee
です。これは複数のテーブルから構成できます。 Task
フォームページに
# Models
class Transaction < ApplicationRecord
has_many :tasks
has_many :borrowers
has_many :partners
# Combine into a single array to display on the collection_select
def assignees
borrowers + partners
end
end
class Task < ApplicationRecord
# has attribute :assignee_type_and_id (string)
belongs_to :transaction
# Reverse engineer single attribute into type/id parts
def assignee
if assignee_type_and_id
parts = assignee_type_and_id.split(".")
type = parts.first
id = parts.last
if type.to_s.downcase == "borrower"
Borrower.find(id)
elsif type.to_s.downcase == "partner"
Partner.find(id)
end
end
end
end
class Borrower < ApplicationRecord
# has attribute :name
belongs_to :transaction
def type_and_id
"borrower.#{id}"
end
end
class Partner < ApplicationRecord
# has attribute :name
belongs_to :transaction
def type_and_id
"partner.#{id}"
end
end
、私はBorrowers
とPartners
の両方を兼ね備えた、単一のHTML select
をしたいです。
古典的な多型はassignee_type
列を追加するように言いましたが、今は1つではなく2つのフィールドで作業しています。
私の解決方法は、最終値がassignee_type.assignee_id
の形式になるように、これらの2つを1つの選択に組み合わせることです。
# form.html.erb
<%= form_for @task do |f| %>
<%= f.label :assignee_type_and_id, "Assignee" %>
<%= f.collection_select :assignee_type_and_id, @transaction.assignees, :name, :type_and_id %>
<% end %>
形態をフォーマットborrower.123
で、そのポスト値、partner.57
等提出され、その値がDB列に格納されます。
実際のタスクのAssignee
を取得するには、Task#assignee
メソッドで前述したように少しリバースエンジニアリングを行う必要があります。
質問
は、これを行うために、より適切な方法はありますか?私はこれを思いつきました。これは、私のような問題が私よりもずっと賢い人によって解決されているに違いないことを知っているからです。...自分のハイブリッドバージョン?
更新
私はこの非常に事をやるようですRailsの4.2 + GlobalID、時に起こりました。それを使用しない理由がない限り、私は自分自身の "乱暴な"バージョンの代わりにその実装を使うかもしれません。このような状況に対して、より良い解決策はありますか?