如何优雅地为具有多态关联的模型构造表单? [英] How can I elegantly construct a form for a model that has a polymorphic association?

查看:91
本文介绍了如何优雅地为具有多态关联的模型构造表单?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的模特:

class Lesson < ActiveRecord::Base
  belongs_to :topic, :polymorphic => true  
  validates_presence_of :topic_type, :topic_id  
end

class Subject < ActiveRecord::Base  
   has_many :lessons, :as => :topic  
end

class Category < ActiveRecord::Base  
  has_many :lessons, :as => :topic  
end

现在,我需要的是一个允许用户创建或更新课程的表格.问题是,如何提供包含主题和类别混合的选择菜单? (对于用户而言,在此特定表单上,主题"和类别"是可以互换的,但在其他情况下并非如此.)

Now, what I need is a form that will allow the user to create or update Lessons. The questions is, how can I provide a select menu that offers a mix of Subjects and Categories? (To the user, on this particular form, Subjects and Categories are interchangeable, but that's not the case elsewhere.)

理想情况下,它看起来像这样:

Ideally, this would look something like this:

views/lessons/_form.html.haml

views/lessons/_form.html.haml

= simple_form_for(@lesson) do |f|
  = f.input :title
  = f.association :topic, :collection => (@subjects + @categories)

那是行不通的,因为我们只需要指定topic_id,我们也需要topic_types.但是,我们如何指定这些值呢?

That won't work because we'd only be specifying the topic_id, and we need the topic_types as well. But how can we specify those values?

我想问题的症结在于,我真的想要一个选择菜单,该菜单指定与两个不同属性(topic_id和topic_type)相对应的两个值.有任何优雅的讽刺方法吗?

I guess the crux of the problem is that I really want a single select menu that specifies two values corresponding to two different attributes (topic_id and topic_type). Is there any elegant railsy way to do this?

一些注意事项:

a)单表继承可以解决这个问题,但是我想避免这种情况,因为类别和主题具有自己的关系……我将为您省去细节.

a) Single table inheritance would make this issue go away, but I'd like to avoid this, as Categories and Subjects have their own relationship… I'll spare you the details.

b)我可能会拉一些javascript恶作剧,是吗?但这听起来很杂乱,而且如果有更清洁的方法来执行此操作,可以使用一些魔术辅助方法之类的东西,那当然是更好的选择.

b) I might could pull some javascript shenanigans, yes? But that sounds messy, and if there's a cleaner way to do it, some magic form helper or something, then that's certainly preferable.

c)尽管我使用的是simple_form,但我不愿意为此而烦恼,以防万一,这很复杂.

c) Though I'm using simple_form, I'm not wedded to it, in case that's complicating matters.

谢谢

推荐答案

如果您不希望使用STI,则可以执行类似的操作:创建一个新模型Topic(name:string),它将多态引用Subject.

If you don't wish to use STI, you can do something similar: create a new model Topic(name:string) which will polymorphically reference Subject or Category.

class Lesson < ActiveRecord::Base
  belongs_to :topic
  validates_presence_of :topic_id  
end

class Topic < ActiveRecord::Base
  belongs_to :topicable, :polymorphic => true
end

class Subject < ActiveRecord::Base
   has_one :topic, :as => :topicable
   has_many :lessons, :through => :topic
   accepts_nested_attributes_for :topic
end

class Category < ActiveRecord::Base  
   has_one :topic, :as => :topicable
   has_many :lessons, :through => :topic
   accepts_nested_attributes_for :topic
end

在创建新的主题/类别的视图中:

In the view where you create a new Subject/Category:

<%= form_for @subject do |subject_form| %>
  <%= subject_form.fields_for :topic do |topic_fields| %>
    <%= topic_fields.text_field :name %>
  <% end %>
<% end %>

这篇关于如何优雅地为具有多态关联的模型构造表单?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆