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
- 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.
- 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
Getting Only New Mail from an Imap Server
Ruby on Rails Advanced JSON Serialization
Repairing Postgresql After Upgrade to Osx Mavericks
Install Bundler Gem Using Ansible
Verify Client Certificate Using Sslserver in Ruby
How to Test Code Coverage for Rails Erb Templates
Why Is 'Return a or B' a Void Value Expression Error in Ruby
Ruby on Rails: Devise, Want to Add Invite Code
Executing User-Supplied Ruby Code on a Web Server
Tell the End of a .Each Loop in Ruby
How to Spawn an Eventmachine "Inside" a Rails App
How to Set an Option as Selected Using Selenium Webdriver (Selenium 2.0) Client in Ruby
How to Format a Number 1000 as "1 000"