Rails:多态关联 - 在表单中创建子项并选择父

时间:2017-03-05 17:23:56

标签: ruby-on-rails

为了说明我的问题,我将使用ruby指南中列出的多态关联的以下关联:

class Picture < ApplicationRecord
  belongs_to :imageable, polymorphic: true
end

class Employee < ApplicationRecord
  has_many :pictures, as: :imageable
end

class Product < ApplicationRecord
  has_many :pictures, as: :imageable
end

现在在我们的:pictures表中,我们将有两个不同的列,即imageable_idimageable_type

我不清楚的第一件事是,imageable_type到底是什么?宣布imageable_id时,“rails magic”会自动填满吗?

继续我的下一点(这可能会间接回答我上面的不确定性),如何为我的Product表单分配EmployeePicture.new

#create new picture form
#assume pre_created_array holds the :id for both Employee & Product
<%= form_for @picture do |f| %>
  #relevant fields ontop
  #choosing parent field is the one im unsure of      
  #this is what i assumed might be correct(?)
  <%= f.select :imageable_id, options_for_select(pre_created_array) %>
<% end %>

现在这个表单确实有效吗?是否需要在控制器操作中处理关联的构建?我实际上不太确定,因为通常在常规关联中,可以在.save之前声明父级,例如执行@post.employee = #find an employee。那么我们是否应该阅读:imageable_id

#pictures controller

def create
  @picture = Picture.new(picture_params)
  #manipulate :imageable_id here???
  if @picture.save
    #blahblah other code
end

所以我实际上对此非常不确定,它是否应该是处理关联建立的形式或控制器。这就是为什么我提出这两个“不确定性”的原因。

1 个答案:

答案 0 :(得分:0)

多态关联很酷,因为它允许单个表格belong_to多个,如您所知。所以给定picture,我们不必知道它是属于employee还是product,我们只需要调用picture.imageable并获取父级。

因此,如果我们不必知道父母的位置,那必须意味着 Rails 必须知道。怎么知道的? imageable_typeimageable_type是它所属的类的名称。在这种情况下,'Employee''Product'。这样,给定imageable_id,它知道要搜索哪个表。

image.imageable实际上会调用image.imageable_type.constantize.find(image.imageable_id)

如果你只是分配对象而不是ID,Rails会为你做这个“魔术”。 image.update(imageable: Product.first)将为您分配两个。

因此,在您的表单中,您应该能够使用一组对象,并让Rails为您完成剩下的工作。