2

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 :event_users
  accepts_nested_attributes_for :event_users
end

class Event < ActiveRecord::Base
  has_many :event_users
  has_many :users, :through => :event_users
  accepts_nested_attributes_for :users
end

class EventUser < ActiveRecord::Base
  set_table_name :events_users
  belongs_to :event
  belongs_to :user
  accepts_nested_attributes_for :events
  accepts_nested_attributes_for :users
end

And also the table-layout

event_users
  user_id
  event_id
  user_type
events
  id
  name
users
  id
  name

And this is my form

<%= semantic_form_for @event do |f| %>
  <%= f.semantic_fields_for :users, f.object.users do |f1| %>
    <%= f1.text_field :name, "Name" %>
    <%= f1.semantic_fields_for :event_users do |f2| %>
      <%= f2.hidden_field :user_type, :value => 'participating' %>
    <% end %>
  <% end %>
<%= link_to_add_association 'add task', f, :users %>
<% end %>

The problem is that if I create a new user this way, it doesn't set the value of user_type (but it creates a user and a event_users with user_id and event_id). If I go back to the edit-form after the creation of a user and submit, then the value of user_type is set in events_users. (I have also tried without formtastic) Any suggestions? Thanks!

----edit----

I have also tried to have the event_users before users

<%= semantic_form_for @event do |f| %>
  <%= f.semantic_fields_for :event_users do |f1| %>
    <%= f1.hidden_field :user_type, :value => 'participating' %>
    <%= f1.semantic_fields_for :users do |f2| %>
      <%= f2.text_field :name, "Name" %>
    <% end %>
  <% end %>
<%= link_to_add_association 'add task', f, :event_users %>
<% end %>

but then it only throws me an error:

User(#2366531740) expected, got ActiveSupport::HashWithIndifferentAccess(#2164210940)

--edit--

the link_to_association is a formtastic-cocoon method (https://github.com/nathanvda/formtastic-cocoon) but I have tried to do other approaches but with the same result

---edit----

def create
  @event = Event.new(params[:event])
  respond_to do |format|
    if @event.save
      format.html { redirect_to(@event, :notice => 'Event was successfully created.') }
      format.xml  { render :xml => @event, :status => :created, :location => @event }
    else
      format.html { render :action => "new" }
      format.xml  { render :xml => @event.errors, :status => :unprocessable_entity }                 
    end
  end
end
Andrew Grimm
  • 78,473
  • 57
  • 200
  • 338
jonepatr
  • 7,769
  • 7
  • 30
  • 53

2 Answers2

2

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!
nathanvda
  • 49,707
  • 13
  • 117
  • 139
  • Wow! I can't believe you actually solved this! You are my hero! Thank you so much!! The reason behind why the organizer adds all the participants, is that event is added after the actual event, to solve economic-related stuff that occurred during the event. Yes, I'm adding existing users to! Thanks again!! – jonepatr Jan 20 '11 at 00:21
  • Do you have any idea how to add user_type to a user(existing) selected from a multi-dropdown? – jonepatr Jan 20 '11 at 01:42
  • In the `_event_user_fields` partial i now automatically create a new user. Instead of doing that, you could two links: 1 to add a new user, and 1 to add an existing user from a dropdown. Is that clear enough? – nathanvda Jan 20 '11 at 08:08
  • You wouldn't want take a look at my very similar issue would ya? http://stackoverflow.com/questions/11199572/rails-3-2-has-many-through-form-submission – ctilley79 Jun 26 '12 at 03:14
0

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.

Costa Walcott
  • 867
  • 6
  • 16