我如何处理rails has_many中的复选框?

时间:2013-02-24 04:49:23

标签: ruby-on-rails ruby ruby-on-rails-3 ruby-on-rails-3.2 form-for

好的,我有数据模型

class Application < ActiveRecord::Base
  has_many :schedules

class Schedule < ActiveRecord::Base
 belongs_to :application
 belongs_to :time_slot
 attr_accessible :time_slot_id, :application_id, :day


class TimeSlot < ActiveRecord::Base
  attr_accessible :end_time, :friday, :name, :saturday, :start_time, :sunday, :thursday, :tuesday, :wednesday

基本上当有人填写一个应用程序时,我会有一个日历视图,提示他们选择这些日期的时间段......例如,我将在星期二列出4个时隙,用户可以不选择所有的时段。

我的问题是:有没有办法为每个时段创建复选框。因此,如果用户为星期三选择4个插槽,星期五选择3个插槽,我可以使用params传递它,并使用day,time_slot_id和application_id创建新的计划记录。

这是我到目前为止,我有时间段显示但不知道如何创建创建新记录的复选框

= form_for(@application) do |f|

  %tr
    - ['friday', 'saturday', 'sunday'].each do |day|
      %td
        - time_slots(day).each do |slot|
          %p{:style => "font-size: 12px;"}= "#{slot.name} (#{custom_time(slot.start_time)} - #{custom_time(slot.end_time)})"

1 个答案:

答案 0 :(得分:1)

您可以在check_box_tag

中添加time_slots
- time_slots(day).each do |slot|
  = check_box_tag 'application[time_slot_ids][]', slot.id, f.object.time_slots.include?(slot)
  %p{:style => "font-size: 12px;"}= "#{slot.name} (#{custom_time(slot.start_time)} - #{custom_time(slot.end_time)})"

这将为每个时间段添加一个check_box。当您向应用程序模型添加time_slot_ids时,它将使用has_many提供的has_many :time_slots方法。

# application.rb
has_many :schedules
has_many :time_slots, through: :schedules

更新:一些陷阱。

如果没有选择时间段,您可能会看到表单似乎没有保存,您仍然可以获得与应用程序关联的旧时隙。这是因为没有time_slot_ids传递给控制器​​。要防止这种情况,您需要添加

check_box_tag 'application[time_slot_ids][]', nil

#each块之前,所以当没有选中复选框时,它总是发送一些内容。

您想要更改的另一件事是检查是否选择了时间段的部分。

f.object.time_slots.include?(slot)

如果时间段没有加载,这将在每个时间段点击数据库。您可以做的一件事是添加一个实例变量来保存当前应用程序的time_slot_ids并将其与块中的插槽进行对比

# controller
@time_slot_ids = @application.time_slot_ids

# view
@time_slot_ids.include?(slot.id)