Ruby on Rails: Devise, Want to Add Invite Code

Ruby on rails: Devise, want to add invite code?

1) A virtual attribute usually needs a setter in addition to a getter.

Easiest way is to add

attr_accessor :invite_code
attr_accessible :invite_code # allow invite_code to be set via mass-assignment
# See comment by James, below.

to the User model

2) I presume that Devise wants the User model to validate. So you could stop the validation by adding

validates_each :invite_code, :on => :create do |record, attr, value|
record.errors.add attr, "Please enter correct invite code" unless
value && value == "12345"
end

NOTE: added :on => :create since the invite_code is only needed for creating the new user, not for updating.

Devise invite code

This should be a fairly straight forward process, as the number of invitations a user has is just an integer stored in your database. It could be something as simple as:

def level_up(level)
self.invitation_limit += level
self.save
end

While a very simple implementation, you just pass in the users level, add it to their current number of invitations, and save the user. It all really depends on how fancy you want to get, but it really comes down to basic math, and saving it to the database.

Invite Links with Devise

You could create specific route for this links, like eg /r/1234 (where 1234) is referrer code assigned to Referrer.

Once referee go through this link in assigned to this route controller you set the cookie referrer=1234 and redirect to signup page.

Let's add to User model :referrer_code_on_signup attribute:

class User < ApplicationRecord
attr_accessor :referrer_code_on_signup
after_commit :grand_rewards, on: create
# ... other user stuff

private

def grand_rewards
return unless referrer_code_on_signup.present?

# some rewards logic
end
end

In case if referee will pass signup form and submit it you should tweak registrations controller:

# app/controllers/registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController
def new
if cookies[:referrer].present?
build_resource(referrer_code_on_signup: cookies[:referrer])
else
build_resource
end
end
end

And then tell devise to use that controller instead of the default with:

# app/config/routes.rb
devise_for :users, :controllers => {:registrations => "registrations"}

For the special route:
You could create ReferrerController:

# app/controllers/referrers_controller.rb
class ReferrersController < ApplicationController
before_action :set_referrer

# Endpoint for share referrer link like example.com/r/123456 - redirects to
# sign in page and setup referrer cookies
def show
cookies[:referrer] = @referrer.referrer_code if @referrer.present?
redirect_to user_sign_up_path
end

private

def set_referrer
@referrer = User.find_by(referrer_code: params[:id])
end
end

And update your routes with line:

resources :referrers, only: :show, path: :r

We assume your User model has referrer_code stored at DB and assigns random, unique value on signup

Rails: invite to sign up as friend with devise gem


  1. If there is any better way of doing this, gems or codes.

You may use devise-inviteable gem. For friendship create you can customize this gem.


  1. I didn't find good resources on customize Devise's Signup Controller, can I extract the logic to another place, store the invite code, and then continue creating friendship model?

To customise Devise Signup you need to inherit Devise::RegistrationsController

class RegistrationsController < Devise::RegistrationsController
def create
super
# Now write your customize code for friendship
end
end

And then tell devise to use that controller instead of the default with:

# app/config/routes.rb
devise_for :users, :controllers => {:registrations => "registrations"}

Override Devise Invitable `invite!` method in order to add attachment to invitation email - Rails

DeviseInvitable has a usefull skip_invitation option.
With the following method you can easily use your own mailer and add attachment in it :

def invite_and_notify_user(email)
user = User.invite!({ email: email }) do |u|
u.skip_invitation = true
end
notify_by_email(user)
end


def notify_by_email(user)
MyUserMailer.invited_user_email(user).deliver
end

In MyUserMailer class:

  def invited_user_email(user)
@user = user
attachments['terms.pdf'] = File.read('/path/terms.pdf')
mail(to: user.email, from: 'contact@mail.com', subject: "Your subject")
end

Devise Invitable invitation to accept an event?

I think devise_invitable is not designed for your use case; it's intended use is for invitation-only user registration. That is, you only want people to be able to sign up for an account on your site if they've been invited to do so and have a special invitation code. That's an authentication problem (which is why there's a devise addon that's a solution for it) -- you need to use tokens in order to authenticate invited users who have not yet registered a password.

Your problem appears very different, at least superficially -- it sounds like you just want to implement a user interface for already-authenticated users.



Related Topics



Leave a reply



Submit