简体   繁体   中英

Trouble with Rails 3 has_many :through association and views/forms

I have previously used has_and_belongs_to_many associations in my older Rails apps but am moving to using has_many, :through for new and current apps. However, I believe I am missing something central to the has_many, :through association in Rails 3.

Currently, I am building an app for our town's volunteer fire department. When we have a meeting, we want to check off whether or not a fire fighter is present, excused, or absent.

My models:

#FireFighter Model
class FireFighter < ActiveRecord::Base
has_many :attendance_meetings
has_many :meetings, :through => :attendance_meetings
accepts_nested_attributes_for :meeting

#Meeting Model
class Meeting < ActiveRecord::Base
has_many :attendance_meetings
has_many :fire_fighters, :through => :attendance_meetings
accepts_nested_attributes_for :fire_fighter

#AttendanceMeeting Model
class AttendanceMeeting < ActiveRecord::Base
attr_accessor :status # this is the added property on the join model that we need populated
belongs_to :fire_fighter
belongs_to :meeting

The problem I'm having is how to set this up in the view. Currently, I have:

= hidden_field_tag "meeting[fire_fighter_ids][]"
-@meeting.fire_fighters.each do |fire_fighter|
  = fire_fighter.fire_fighter_name 
  %span.radio_btn= radio_button_tag :fire_figher_ids, fire_fighter.id, "present"
  present
  %span.radio_btn= radio_button_tag :fire_figher_ids, fire_fighter.id, "excused"
  excused
  %span.radio_btn= radio_button_tag :fire_figher_ids, fire_fighter.id, "absent"
  absent
  %br

This will spit out each fire fighter and three radio buttons for each fire fighter (with options for present, excused, or absent). However, the name of the resulting radio buttons are all the same, so you can only pick one for all fire fighters.

As I noted above, I feel certain I am missing something basic but I am stumped. I've read through tons of SO questions and The Rails 3 Way book's sections on ActiveRecord. Any suggestions or directions would be most appreciated. Thank you!

It should be something like:

class Meeting < ActiveRecord::Base
  has_many :attendance_meetings
  has_many :fire_fighters, :through => :attendance_meetings
  accepts_nested_attributes_for :attendance_meetings

# view
= form_for @meeting do |f|
  = f.fields_for :attendance_meetings do |f_a_m|
    = f_a_m.object.fire_fighter.name
    = f_a_m.check_box :status, 'present'
    = f_a_m.check_box :status, 'excused'
    = f_a_m.check_box :status, 'absent'

For the approach you're taking you need to build the association for each firefighter with the meeting. Something like:

@meeting.firefighters << Firefighter.all

This doesn't seem particularly optimal however. I would form the join with a boolean :status for those who are absent (t) or excused (f) with present not included, imagine it like meeting_absentees. Seems backward but in this way your table will have far fewer rows.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM