mercredi 1 avril 2015

"Invitation to Event" feature in Rails w/ best practices

I'm trying to write more efficient and readable code in Rails, and right now I'm working on an app which requires a type of invitation system. In this app I have an Event model. Users can create events. User's can request invitations from the owner of an event, and the owner of an event can offer invitations to users.


Invitation Offer



  1. Alex creates an event.

  2. Alex offers Mike an invitation to his event.

  3. Mike rejects Alex's invitation.


Invitation Request



  1. Bob creates an event.

  2. John requests an invite to Bob's event.

  3. Bob accepts John's invite request.


Once the owner accepts an invitation request, that user must be linked to the Event model somehow, possibly through a Guest model.


If I can get some advice on invitation requests, I think I can figure out the 'offer an invitation' side of the problem on my own. Here's what I have so far:


Schema



create_table "invitations", force: :cascade do |t|
t.integer "inviter_id" #event owner (maybe change field name)
t.integer "invitee_id" #guest
t.text "greeting"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.boolean "is_request"
t.string "status" #set to accepted, waiting, or rejected
t.integer "event_id"
end


Model



class Invitation < ActiveRecord::Base

after_create :send_notification

belongs_to :event
belongs_to :invitee, class_name: 'User'
belongs_to :inviter, class_name: 'User'

def inviter
event.user
end

def send_notification
if self.is_request?
self.inviter_notification #notify event owner of invitation request
else
self.invitee_notification #notify potential guest of invitation
end
end

#using Mailboxer to send notifications
def invitee_notification
subject = "#{inviter.name} has invited you to attend #{event.title}"
body = self.greeting
invitee.notify(subject, body, self)
end

def inviter_notification
subject = "#{invitee.name} has requested an invitation to #{event.title}"
body = self.greeting
inviter.notify(subject, body, self)
end

end


Controller



def create
@invitation = Invitation.new
#TODO invitation_params method not working for some reason
@invitation.invitee_id = params[:invitee_id]
@invitation.meetup_id = params[:meetup_id]
@invitation.message = params[:message]
@invitation.is_request = params[:is_request]

respond_to do |format|
if @invitation.save
format.html { redirect_to :back, notice: 'Invitation was successfully sent.' }
else
format.html { redirect_to session.delete(:return_to), notice: 'Invitation failed to send.' }
end
end
end


What's missing is a way for users to actually accept and deny requests and offers. How could I do that RESTfully?


I'm not sure if a single Invitation resource is the best way to go, because of the separate Offer and Request stories. I was thinking about renaming the resource to OfferInvitation and creating a RequestInvitation resource. Requesting invites is actually more important than offering, and I've kind of just shoved the functionality in there with the is_request? field.


I'd appreciate any advice on how this code could be improved, and how I might implement the accepting and denying of requests and offers, and then linking the resulting guest to the Event model. Do you think a Guests table is necessary (so that I can do myEvent.guests), or would it be better to create a scope to find accepted Invitations?


I'm pretty new to best-practices and refactoring code, so having a good solution to this would help me a lot with future coding. Hope this wasn't too longwinded.


Thanks.


Aucun commentaire:

Enregistrer un commentaire