2017-03-03 4 views
1

これは、多形関連のややユニークなバージョンです。それは私が解決しようとしている苦労している多くの良い答えに出くわしていない "実世界"の問題の一つです。形式での多形関連のレンダリング

Transactionレコードは多くがTasksであり、各TaskAssigneeです。これは複数のテーブルから構成できます。 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 

、私はBorrowersPartnersの両方を兼ね備えた、単一の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、時に起こりました。それを使用しない理由がない限り、私は自分自身の "乱暴な"バージョンの代わりにその実装を使うかもしれません。このような状況に対して、より良い解決策はありますか?

答えて

関連する問題