Last active
October 30, 2015 09:41
-
-
Save superp/b0458872ce0e202c7c6f to your computer and use it in GitHub Desktop.
Invite module
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Account < ActiveRecord::Base | |
include SimpleTree | |
include Invitation | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'securerandom' | |
module Invitation | |
extend ActiveSupport::Concern | |
included do | |
before_create :generate_invitation_token | |
define_model_callbacks :invite, :only => [:after, :before] | |
scope :inviter, lambda { |token| where(:invitation_token => token) } | |
end | |
module ClassMethods | |
# Generate a token checking if one does not already exist in the database. | |
def invitation_token | |
generate_token(:invitation_token) | |
end | |
# Generate a token by looping and ensuring does not already exist. | |
def generate_token(column, limit=8) | |
loop do | |
token = ::SecureRandom.base64(16).tr('+/=lIO0', 'pqrsxyz').slice(0, limit) | |
break token unless where({ column => token }).exists? | |
end | |
end | |
def find_invite!(token) | |
invitor = inviter(token).first | |
raise ActiveRecord::RecordNotFound, "Invitor by #{token} not found" if invitor.nil? | |
invitor | |
end | |
end | |
# Join account by set parent record | |
def invite(account) | |
if account && account.parent.nil? && account != self && !account.children.where(:id => id).exists? | |
run_callbacks :invite do | |
account.parent_id = self.id | |
account.save(:validate => false) | |
end | |
end | |
!account.nil? && account.parent == self | |
end | |
protected | |
# Generates a new random token for invitation, and stores the time | |
# this token is being generated | |
def generate_invitation_token | |
self.invitation_token = self.class.invitation_token | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class InvitationsController < ApplicationController | |
before_filter :find_invitor | |
def show | |
if account_signed_in? | |
@invitor.invite(current_account) | |
redirect_to account_dashboard_path | |
else | |
cookies[:invite] = @invitor.invitation_token | |
redirect_to root_path | |
end | |
end | |
protected | |
def find_invitor | |
@invitor = Writer.find_invite!(params[:id]) | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class SessionsController < ActionController::Metal | |
def create | |
... | |
redirect_to account_callback_path(resource) | |
end | |
protected | |
def account_callback_path(resource) | |
... | |
if inviter = find_inviter | |
"/invitations/#{inviter.invitation_token}" | |
else | |
... | |
end | |
end | |
def find_inviter | |
token = request.cookie_jar[:invite] || params['invite'] || request.env['omniauth.params']['invite'] | |
token.blank? ? nil : Account.find_invite(token) | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module SimpleTree | |
extend ActiveSupport::Concern | |
included do | |
belongs_to :parent, | |
:class_name => self.base_class.to_s, | |
:foreign_key => :parent_id, | |
:inverse_of => :children, | |
:counter_cache => :children_count | |
has_many :children, | |
:class_name => self.base_class.to_s, | |
:foreign_key => :parent_id, | |
:inverse_of => :parent | |
scope :roots, lambda { where(:parent_id => nil) } | |
scope :with_children, lambda { where("#{quoted_table_name}.children_count > 0") } | |
end | |
def has_children? | |
!children_count.zero? | |
end | |
def root? | |
parent_id.nil? | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment