4

这是我的模型:

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

现在,我需要一个允许用户创建或更新课程的表单。问题是,我如何提供一个包含主题和类别的选择菜单?(对于用户来说,在这个特定的表单上,主题和类别是可以互换的,但在其他地方并非如此。)

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

意见/课程/_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) 单表继承可以解决这个问题,但我想避免这种情况,因为类别和主题有它们自己的关系……我就不详细说明了。

b)我可能会拉一些javascript恶作剧,是吗?但这听起来很混乱,如果有更清洁的方法,一些魔法形式的助手或其他东西,那么这当然是可取的。

c) 虽然我使用的是 simple_form,但我并不喜欢它,以防万一事情变得复杂。

谢谢

4

2 回答 2

-1

如果你不想使用 STI,你可以做类似的事情:创建一个新模型Topic(name:string),它将多态引用SubjectCategory.

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 %>
于 2011-07-11T16:31:07.440 回答
-1

在考虑了这一点之后,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'));
});

笔记:

  • 我使用单选按钮在列表中选择主题(类别或主题)
  • 每个可能主题的类名存储在属性“数据类型”中
  • 选中单选按钮时,通过JS将类名复制到隐藏输入
  • 使用:HTML5、jQuery、haml、simple_form
于 2013-09-17T04:23:24.540 回答