Rails 3, nested multi-level forms and has_many through

前端 未结 2 828
没有蜡笔的小新
没有蜡笔的小新 2020-12-13 03:17

I\'m trying to get it to work but it dosen\'t!

I have

class User < ActiveRecord::Base
  has_many :events, :through => :event_users
  has_many          


        
相关标签:
2条回答
  • 2020-12-13 03:37

    To be honest, i have never tried to edit or create a has_many :through in that way.

    It took a little while, and had to fix the js inside formtastic_cocoon to get it working, so here is a working solution.

    You need to specift the EventUser model, and then fill the User model (the other way round will never work).

    So inside the models you write:

    class Event < ActiveRecord::Base
      has_many :event_users
      has_many :users, :through => :event_users
      accepts_nested_attributes_for :users, :reject_if => proc {|attributes| attributes[:name].blank? }, :allow_destroy => true
      accepts_nested_attributes_for :event_users, :reject_if => proc {|attributes| attributes[:user_attributes][:name].blank? }, :allow_destroy => true
    end
    
    class EventUser < ActiveRecord::Base
      belongs_to :user
      belongs_to :event
      accepts_nested_attributes_for :user
    end
    
    class User < ActiveRecord::Base
      has_many :events, :through => :event_users
      has_many :event_users
    end
    

    Then the views. Start with the events/_form.html.haml

    = semantic_form_for @event do |f|
      - f.inputs do
        = f.input :name
    
        %h3 Users (with user-type)
        #users_with_usertype
          = f.semantic_fields_for :event_users do |event_user|
            = render 'event_user_fields', :f => event_user
          .links
            = link_to_add_association 'add user with usertype', f, :event_users
    
        .actions
          = f.submit 'Save'
    

    (i ignore errors for now) Then, you will need to specify the partial _event_user_fields.html.haml partial (here comes a little bit of magic) :

    .nested-fields
      = f.inputs do
        = f.input :user_type, :as => :hidden, :value => 'participating'
        - if f.object.new_record?
          - f.object.build_user
        = f.fields_for(:user, f.object.user, :child_index => "new_user") do |builder|
          = render("user_fields", :f => builder, :dynamic => true)
    

    and to end the _user_fields partial (which does not really have to be a partial)

    .nested-fields
      = f.inputs do
        = f.input :name
    

    This should work. Do note that i had to update the formtastic_cocoon gem, so you will need to update to version 0.0.2.

    Now it would be easily possible to select the user_type from a simple dropdown, instead of a hidden field, e.g. use

    = f.input :user_type, :as => :select, :collection => ["Participator", "Organizer", "Sponsor"]
    

    Some thoughts (now i proved it works):

    • this will always create new users on the fly, actually eliminating the need for the EventUser. Will you allow selecting existing users from a dropdown too?
    • personally i would turn it around: let users assign themselves to an event!
    0 讨论(0)
  • 2020-12-13 03:40

    Does the events_users model not have an ID column? Since there's an additional field (user_type) then EventUser is a model and should probably have an ID. Maybe that's why user_type isn't being set in your first case.

    0 讨论(0)
提交回复
热议问题