I’ve created a simple Rails application where users can register to attend events. To create a pleasing user experience, an unidentified user can browse the events and then if they see one they’d like to event they can click ‘register for the event’. Using Twitter Bootstrap, the application then presents the user with a modal (popup) asking them to register first, to attend the event.
The form on the modal is as follows:
simple_form_for @user do |f|
f.input :name, :placeholder => "Name", :label => false
f.input :email, :placeholder => "Email", :label => false
f.input :postcode, :placeholder => "Postcode", :label => false
hidden_field_tag :event_id, @event.id
f.button :submit, "Sign me up for this event"
end
So, you can see that basically I pass in an event_id value to the user controller’s create action. To handle this the create action becomes:
def create
if params[:event_id].blank?
event_registration = false
else
event_id = params[:event_id].to_s
event_registration = true
end
if event_registration == true
# The user is being created as part of signing up to an event
@user_check = User.find_by_email(params[:user][:email])
unless @user_check.nil?
# The user already exists, but the visitor forgot
@user = @user_check
else
# The user is a new sign up
@user = User.new(params[:user])
end
# Now create the attendance for the user
@event = Event.find(event_id)
@attendance = @event.attendances.new
@attendance.attendee = @user
@attendance.save
redirect_target = event_attendance_thank_path(@event, @attendance)
else
# The user is being created cleanly
@user = User.new(params[:user])
end
if @user.save
redirect_to root_path, notice: "Thanks for signing up, check your email"
else
# We should destroy the failing attendance?
redirect_to root_path, alert: "Something's up with the signup. Have you already registered with this email address?"
end
end
To me, handling this level of complexity in the controller feels messy, and I’m wondering what better ways I might go about this?
Any help or pointers to refactor this would be greatly appreciated.
If it is possible for users that are already signed and logged in to mark their attendance for events, you should use the same piece of code in both places. Just create helper that will mark users’ attendance and call it from both
UsersController#createandEvents#attend(or whatever it is called) actions.Now — if you have heard of “fat model, skinny controller” pattern, you are probably starting to notice it is a place you could use it.
Just create
Usermodel method to attend some event, that will accept id, or event itself as an argument. This way you could simply write in your controller: