[英]Rails polymorphic association in a form
這是多態關聯的略微獨特的版本。 這是我正在努力解決的那些“現實世界”問題之一,並沒有遇到很多好的答案,所以我自己做了。
Transaction
記錄有許多Tasks
,每個Task
都有一個Assignee
,可以來自多個表。
# 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
在Task
表單頁面,我想一個HTML select
是結合了Borrowers
及Partners
。
經典多態性說要添加一個assignee_type
列,但現在我正在使用2個字段而不是一個字段。
我的解決方案是將這兩個組合成一個選擇,使得最終值的格式為assignee_type.assignee_id
。
# 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
等格式POST值,該值存儲在DB列中。
當我想要檢索實際任務的Assignee
,我必須在Task#assignee
方法中進行一些逆向工程。
題
有沒有更合適的方法來做到這一點? 我自己想出了這個,這讓我感到害怕,因為我知道這樣的問題一定是由比我聰明的人解決的......
有沒有辦法讓這個工作與“正常”多態,而不是強制我自己的混合版本?
更新
我遇到了Rails 4.2+ GlobalID,它似乎做了這件事。 除非有理由不使用它,否則我可能會使用該實現而不是我自己的“bastardized”版本。 這樣的情況有沒有更好的解決方案?
對於表單跨越多個模型/復雜關聯的這些類型的問題,我使用表單支持對象。 它保持一切清潔和模塊化。 這是一篇很好的文章: https : //content.pivotal.io/blog/form-backing-objects-for-fun-and-profit
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.