簡體   English   中英

Rails在表單中的多態關聯

[英]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是結合了BorrowersPartners

經典多態性說要添加一個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.123partner.57等格式POST值,該值存儲在DB列中。

當我想要檢索實際任務的Assignee ,我必須在Task#assignee方法中進行一些逆向工程。

有沒有更合適的方法來做到這一點? 我自己想出了這個,這讓我感到害怕,因為我知道這樣的問題一定是由比我聰明的人解決的......

有沒有辦法讓這個工作與“正常”多態,而不是強制我自己的混合版本?

更新

我遇到了Rails 4.2+ GlobalID,它似乎做了這件事。 除非有理由不使用它,否則我可能會使用該實現而不是我自己的“bastardized”版本。 這樣的情況有沒有更好的解決方案?

對於表單跨越多個模型/復雜關聯的這些類型的問題,我使用表單支持對象。 它保持一切清潔和模塊化。 這是一篇很好的文章: https//content.pivotal.io/blog/form-b​​acking-objects-for-fun-and-profit

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM