5

I've got an Events model and a Users model joined through an Attendees model. I have figured out how to "Attend" an event as an authenticated user. But what I can't figure out is a nice way to "Withdraw" from an event. I'm sure this is something trivial that I'm missing but what better way to make an entrance into StackOverflow than to ask something trivial? Oh I have been searching railscasts and SO for hours...

Thanks!

views/events/show.html.erb

<p><strong>Attendees: </strong>
    <ul>
        <% for attendee in @event.users %>
            <% if attendee.username == current_user.username %>
                <li><strong><%= attendee.username %></strong>
                    <%= link_to 'Withdraw From Event', withdraw_event_path(@event.id), :method => :post, :class => 'btn btn-danger' %>
                    <%= link_to 'Destroy', @attendee, confirm: 'Are you sure?', method: :delete, :class => 'btn btn-danger' %>
                </li>
            <% else %>
                <li><%= attendee.username %></li>
            <% end %>
        <% end %>   
    </ul>
</p>

/controllers/events_controller.rb

  def attend
    @event = Event.find(params[:id])
    current_user.events << @event
    redirect_to @event, notice: 'You have promised to attend this event.'
  end

  def withdraw
    # I can't get this to work
    redirect_to @event, notice: 'You are no longer attending this event.'
  end

models/event.rb

class Event < ActiveRecord::Base
    attr_accessible :name, :location
    belongs_to :users

    has_many :attendees, :dependent => :destroy
    has_many :users, :through => :attendees

models/user.rb

class User < ActiveRecord::Base
    has_many :events

    has_many :attendees, :dependent => :destroy
    has_many :events, :through => :attendees

models/attendee.rb

class Attendee < ActiveRecord::Base
    belongs_to :event
    belongs_to :user

    attr_accessible :user_id, :event_id

    # Make sure that one user cannot join the same event more than once at a time.
    validates :event_id, :uniqueness => { :scope => :user_id }

end
Brandt
  • 53
  • 1
  • 3

1 Answers1

5

I assume you're having trouble finding the Attendee.

def withdraw
  event    = Event.find(params[:id])
  attendee = Attendee.find_by_user_id_and_event_id(current_user.id, event.id)

  if attendee.blank?
    # handle case where there is no matching Attendee record
  end

  attendee.delete

  redirect_to event, notice: 'You are no longer attending this event.'
end
deefour
  • 34,974
  • 7
  • 97
  • 90
  • 1
    That was it! I knew it was trivial. I forgot that you can just write out a method like that and Rails or Active Record? will piece it together. I hope someone else will find this simple fix useful. – Brandt Jul 09 '12 at 22:59
  • I have very similar code, but I can't find the withdraw_event_path(@event.id) - any ideas on fixing this undefined method error – Marcus Jan 13 '14 at 02:07
  • is there no better way? Attendee.find_by_user_id_and_event_id(current_user.id, event.id) looks ugly :/ – Florian Widtmann Mar 06 '14 at 08:04
  • 2
    @FlorianWidtmann yes it is ugly. :-) It's also deprecated in Rails 4. You can use `Attendee.find_by(user_id: current_user.id, event_id: event.id)` – Jason Gilmore Jul 30 '14 at 20:44