【问题标题】:Rails polymorphic association in a formRails 表单中的多态关联
【发布时间】:2017-03-03 21:13:46
【问题描述】:

这是多态关联的一个稍微独特的版本。这是我正在努力解决的“现实世界”问题之一,但没有找到很多好的答案,所以我自己做了。

一个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 表单页面上,我想要一个结合BorrowersPartners 的HTML select

经典多态性说要添加一个 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 等格式发布值,并将该值存储在 DB 列中。

当我想检索实际任务的Assignee 时,我必须按照上面提到的Task#assignee 方法进行一些逆向工程。

问题

有没有更合适的方法来做到这一点?我自己想出了这个,这让我很害怕,因为我知道这样的问题一定是由比我聪明得多的人解决的......

有没有办法使用“正常”多态性而不是强制使用我自己的混合版本?

更新

我碰巧遇到了 Rails 4.2+ GlobalID,它似乎就是这样做的。除非有理由不使用它,否则我可能会使用该实现而不是我自己的“混蛋”版本。这种情况有没有更好的解决办法?

【问题讨论】:

    标签: ruby-on-rails polymorphism polymorphic-associations


    【解决方案1】:

    对于表单跨越多个模型/复杂关联的这类问题,我使用表单支持对象。它保持一切清洁和模块化。这是一篇很好的文章:https://content.pivotal.io/blog/form-backing-objects-for-fun-and-profit

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-10
      相关资源
      最近更新 更多