I am trying to follow/reproduce this tutorial here https://gorails.com/episodes/referral-program-from-scratch?autoplay=1 Code is here: https://github.com/gorails-screencasts/referral-program
So far my code does create a referral code for each new signup. But it does not record who the referrer was, referred_by. That part is not working.
In my ApplicationController I have:
before_action :set_referred_by_cookie
protected
def set_referred_by_cookie
if params[:ref]
cookies[:referred_by] = {
value: params[:ref],
expires: 30.days.from_now,
}
end
end
It appears this part works bc when I look at this with browser tools I see: Cookie: referred_by=d6733c0da6f0; (but it's not saving to db)
And here's the sample link from the user I created to use for a new signup, so it does look like the ref is converted into the "referred_by" http://localhost:3000/?ref=d6733c0da6f0
Here's my user.rb:
class User < ApplicationRecord
has_prefix_id :user
belongs_to :referred_by, class_name: "User", optional: true
has_many :referred_users, class_name: "User", foreign_key: :referred_by_id
before_validation :set_referral_code
validates :referral_code, uniqueness: true
def set_referral_code
if self.referral_code.nil?
loop do
self.referral_code = SecureRandom.hex(6)
break unless self.class.exists?(referral_code: referral_code)
end
end
end
# Call this from anywhere in your application when the user has completed their referral steps
#after_create :complete_referral!
def complete_referral!
update(referral_completed_at: Time.zone.now)
# TODO: add credit to referred_by user
end
end
Here's registration controller/devise:
class Users::RegistrationsController < Devise::RegistrationsController
invisible_captcha only: :create
protected
def build_resource(hash = {})
if cookies[:referred_by] && referrer = User.find_by(referred_by: cookies[:referred_by])
self.resource.referred_by = referrer
end
self.resource = resource_class.new_with_session(hash, session)
end
def sign_up(resource_name, resource)
sign_in(resource_name, resource)
end
end
It appears that this code in the registration controller isn't working?:
if cookies[:referred_by] && referrer = User.find_by(referred_by: cookies[:referred_by])
self.resource.referred_by = referrer
This is where I'm stuck trying to get the "referred_by" to work, which should add it to "referred_by_id" in database. Ignore the "referral_completed_at", I know that works.. From database:
["referral_code", "ae922a5c9df8"], ["referred_by_id", nil], ["referral_completed_at", nil]]
Your build_resource
is a bit backwards, you need to set self.resource
first then assign referred_by
, and you're searching on the wrong column:
def build_resource(hash = {})
super
if cookies[:referred_by] && referrer = User.find_by(referral_code: cookies[:referred_by])
self.resource.referred_by = referrer
end
end
sign_up
method is also unnecessary.