如何为具有多态关联的模型优雅地构建表单?
这是我的模特:
class Lesson true validates_presence_of :topic_type, :topic_id end class Subject :topic end class Category :topic end
现在,我需要的是一个允许用户创建或更新课程的表单。 问题是,我如何提供一个提供主题和类别混合的选择菜单? (对于用户而言,在此特定表格中,主题和类别是可互换的,但在其他地方并非如此。)
理想情况下,这看起来像这样:
意见/经验/ _form.html.haml
= simple_form_for(@lesson) do |f| = f.input :title = f.association :topic, :collection => (@subjects + @categories)
这不起作用,因为我们只指定topic_id,我们也需要topic_types。 但是我们如何指定这些价值呢?
我想这个问题的症结在于我真的想要一个单一的选择菜单,它指定两个对应于两个不同属性的值(topic_id和topic_type)。 有没有优雅的方式来做到这一点?
几点说明:
a)单表inheritance会使这个问题消失,但我想避免这种情况,因为类别和主题有他们自己的关系……我会饶有你的细节。
b)我可能会拉一些javascript shenanigans,是吗? 但这听起来很混乱,如果有一种更清洁的方式来做,一些神奇的forms助手或其他东西,那么这当然更可取。
c)虽然我使用的是simple_form,但我不会坚持使用它,以防万一这会让事情变得复杂。
谢谢
如果您不想使用STI,您可以执行类似的操作:创建一个新模型Topic(name:string)
,它将多态地引用Subject
或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
在您创建新主题/类别的视图中:
<%= form_for @subject do |subject_form| %> <%= subject_form.fields_for :topic do |topic_fields| %> <%= topic_fields.text_field :name %> <% end %> <% end %>
经过深思熟虑后,IMO聘请JS恶作剧的实施程度越低(b):
= f.input_field :topic_type, as: :hidden, class: 'topic_type' - (@subjects + @categories).each do |topic| = f.radio_button :topic_id, topic.id, {:'data-type' => topic.class.name, class: 'topic_id'}
撒上JS(您的需求可能会有所不同):
$('input:radio.topic_id').change(function() { $('input:hidden.topic_type').val($(this).attr('data-type')); });
笔记:
- 我使用单选按钮在列表中选择主题(类别或主题)
- 每个可能主题的类名存储在属性“data-type”中
- 选择单选按钮时,类名将通过JS复制到隐藏输入
- 使用:HTML5,jQuery,haml,simple_form
- 为什么ActiveRecord :: StatementInvalid:SQLite3 :: SQLException:near“)”:语法错误:INSERT INTO“user_friendships”()VALUES()
- Rails.cache在不同的线程中没有缓存?
- 在这台机器上可用的gem中找不到gem’tzinfo-data(> = 0)x86-mingw32’。 运行bundle install以安装缺少的gem
- 使用DataMapper而不是ActiveRecord
- Rails:Active Record销毁时未初始化的常量错误
- 跳过Model中的某些validation方法
- 如何挽救模型交易并向用户显示错误?
- 如何使用carrierwave将文件发送给用户?
- 如何在公共活动中设置收件人ID