refer 0.0.1 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +129 -9
- data/app/controllers/concerns/refer/controller.rb +15 -0
- data/app/models/concerns/refer/has_referrals.rb +11 -0
- data/app/models/concerns/refer/model.rb +12 -0
- data/app/models/refer/application_record.rb +6 -0
- data/app/models/refer/referral.rb +11 -0
- data/app/models/refer/referral_code.rb +16 -0
- data/db/migrate/20240611180738_create_refer_referrals.rb +11 -0
- data/db/migrate/20240611183349_create_refer_referral_codes.rb +10 -0
- data/lib/generators/refer/model/USAGE +8 -0
- data/lib/generators/refer/model/model_generator.rb +11 -0
- data/lib/refer/engine.rb +1 -0
- data/lib/refer/version.rb +1 -1
- data/lib/refer.rb +41 -1
- metadata +15 -6
- data/app/assets/config/referral_codes_manifest.js +0 -0
- /data/lib/tasks/{referral_codes_tasks.rake → refer_tasks.rake} +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e93783086c4e2c9c226868f818915d002d13258e4a1dc024759921b75763fa5e
|
4
|
+
data.tar.gz: 0477c633957d41edad55c6da672b2ca3fcca1b9a87ea2414e65cf0c6309a458a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6149724a00b0600711afc17d9a035c3f048134b41873f0b44d036cfdd4fbd787182e31f607397034f2b65279eb6130e9c5702677fa0987e32a98bd284d26c32b
|
7
|
+
data.tar.gz: '0562961b931e111932027ba64bbce8f598ad2a85098ac308a874ec5429549d5e6bfdbfca1c8df00d16a7e9d08e154a8043d4d11ccf1b32ea1920e0b0f2376c4e'
|
data/README.md
CHANGED
@@ -1,10 +1,8 @@
|
|
1
1
|
# Refer
|
2
|
-
Referral Codes for Ruby on Rails applications.
|
3
2
|
|
4
|
-
|
5
|
-
How to use my plugin.
|
3
|
+
Referral codes for Ruby on Rails applications.
|
6
4
|
|
7
|
-
## Installation
|
5
|
+
## 📦 Installation
|
8
6
|
Add this line to your application's Gemfile:
|
9
7
|
|
10
8
|
```ruby
|
@@ -16,13 +14,135 @@ And then execute:
|
|
16
14
|
$ bundle
|
17
15
|
```
|
18
16
|
|
19
|
-
|
17
|
+
And add Refer to your model:
|
20
18
|
```bash
|
21
|
-
|
19
|
+
bin/rails generate refer:model User
|
22
20
|
```
|
23
21
|
|
24
|
-
##
|
25
|
-
Contribution directions go here.
|
22
|
+
## 🧑💻 Usage
|
26
23
|
|
27
|
-
|
24
|
+
Refer adds a models to your Rails application for tracking referrals and referral codes.
|
25
|
+
|
26
|
+
To track referrals, you'll need to
|
27
|
+
|
28
|
+
1. Create a referral code
|
29
|
+
2. Set a cookie with the referral code
|
30
|
+
3. Create the referral
|
31
|
+
4. (Optional) Provide a reward for successful referral
|
32
|
+
|
33
|
+
##### Create a referral code
|
34
|
+
|
35
|
+
You can create referral codes through the association:
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
user.referral_codes.create #=> randomly generated code
|
39
|
+
user.referral_codes.create(code: "chris")
|
40
|
+
```
|
41
|
+
|
42
|
+
To customize the referral code generator:
|
43
|
+
|
44
|
+
```ruby
|
45
|
+
Refer.code_generator = ->(referrer) { [id, SecureRandom.alphanumeric(8).join("-") }
|
46
|
+
#=> generates codes like "1-7frb5fUw"
|
47
|
+
```
|
48
|
+
|
49
|
+
By default, Refer will generate 8 character alphanumeric codes.
|
50
|
+
|
51
|
+
##### Set a referral cookie
|
52
|
+
|
53
|
+
To track users, we need to stash the referral code in a cookie when present. By default, Refer will look for `?ref=code` and save this in a cookie.
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
class ApplicationController < ActionController::Base
|
57
|
+
before_action :set_refer_cookie
|
58
|
+
end
|
59
|
+
```
|
60
|
+
|
61
|
+
You can customize the param name with:
|
62
|
+
|
63
|
+
```ruby
|
64
|
+
Refer.param_name = :ref
|
65
|
+
```
|
66
|
+
|
67
|
+
You can customize the cookie name with:
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
Refer.cookie_name = :refer_code
|
71
|
+
```
|
72
|
+
|
73
|
+
##### Refer a user:
|
74
|
+
|
75
|
+
To create a referral, you can run the following
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
class RegistrationsController < ApplicationController
|
79
|
+
def create
|
80
|
+
@user = User.new(user_params)
|
81
|
+
if @user.save
|
82
|
+
refer @user #=> Looks up cookie and attempts referral
|
83
|
+
redirect_to root_path
|
84
|
+
else
|
85
|
+
render :new, status: :unprocessable_entity
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
```
|
90
|
+
|
91
|
+
You can also do this manually:
|
92
|
+
|
93
|
+
```ruby
|
94
|
+
Refer.refer(code: "referral_code", referee: user)
|
95
|
+
```
|
96
|
+
|
97
|
+
Refer will make sure the user has not already been referred and create a Referral.
|
98
|
+
|
99
|
+
##### Check if a user was referred already:
|
100
|
+
|
101
|
+
```ruby
|
102
|
+
Refer.referred?(user)
|
103
|
+
#=> true/false
|
104
|
+
```
|
105
|
+
|
106
|
+
##### Accessing Referrals
|
107
|
+
|
108
|
+
To access a user's referrals, you can use the `referrals` association:
|
109
|
+
|
110
|
+
```ruby
|
111
|
+
user.referrals #=> [Refer::Referral, Refer::Referral]
|
112
|
+
```
|
113
|
+
|
114
|
+
This returns a list of `Refer::Referral` objects.
|
115
|
+
|
116
|
+
##### Accessing Referral
|
117
|
+
|
118
|
+
To access a user's referral, you can use the `referral` association:
|
119
|
+
|
120
|
+
```ruby
|
121
|
+
user.referral #=> Refer::Referral
|
122
|
+
```
|
123
|
+
|
124
|
+
To access a user's referrer, you can use `referrer`:
|
125
|
+
```ruby
|
126
|
+
user.referrer #=> User that referred this User
|
127
|
+
```
|
128
|
+
|
129
|
+
## Providing Referral Rewards
|
130
|
+
|
131
|
+
There are several common ways of handling rewards for successful referrals:
|
132
|
+
|
133
|
+
* Immediate rewards
|
134
|
+
When the referral is successfully created, you can immediately credit the referrer with their reward.
|
135
|
+
|
136
|
+
* Reward after user actions
|
137
|
+
You can check if a user was referred after they complete the action and provide a reward to the referrer.
|
138
|
+
|
139
|
+
* Time-based rewards
|
140
|
+
To provide a reward X days after a successful referral, you can use a schedule job to check for referrals X days ago and provide rewards to those referrers.
|
141
|
+
|
142
|
+
We recommend keeping records for each reward given to a referral so you can limit rewards.
|
143
|
+
|
144
|
+
## 🙏 Contributing
|
145
|
+
If you have an issue you'd like to submit, please do so using the issue tracker in GitHub. In order for us to help you in the best way possible, please be as detailed as you can.
|
146
|
+
|
147
|
+
## 📝 License
|
28
148
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Refer
|
2
|
+
module Controller
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
def set_refer_cookie
|
6
|
+
if (code = params[Refer.param_name])
|
7
|
+
cookies[Refer.cookie_name] = Refer.cookie(code)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def refer(referee)
|
12
|
+
Refer.refer(code: cookies[Refer.cookie_name], referee: referee)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Refer
|
2
|
+
module Model
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
has_many :referral_codes, inverse_of: :referrer, class_name: "Refer::ReferralCode", dependent: :destroy
|
7
|
+
has_many :referrals, inverse_of: :referrer, class_name: "Refer::Referral", dependent: :destroy
|
8
|
+
has_one :referral, inverse_of: :referee, class_name: "Refer::Referral", dependent: :destroy
|
9
|
+
delegate :referrer, to: :referral
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Refer
|
2
|
+
class Referral < ApplicationRecord
|
3
|
+
belongs_to :referrer, polymorphic: true
|
4
|
+
belongs_to :referee, polymorphic: true
|
5
|
+
belongs_to :referral_code, optional: true
|
6
|
+
|
7
|
+
before_validation do
|
8
|
+
self.referrer = referral_code&.referrer
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Refer
|
2
|
+
class ReferralCode < ApplicationRecord
|
3
|
+
belongs_to :referrer, polymorphic: true
|
4
|
+
has_many :referrals, dependent: :nullify
|
5
|
+
|
6
|
+
validates :code, presence: true, uniqueness: true
|
7
|
+
|
8
|
+
before_create if: -> { Refer.code_generator } do
|
9
|
+
Refer.code_generator.call(referrer)
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_param
|
13
|
+
code
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class CreateReferReferrals < ActiveRecord::Migration[7.2]
|
2
|
+
def change
|
3
|
+
create_table :refer_referrals do |t|
|
4
|
+
t.belongs_to :referrer, polymorphic: true, null: false
|
5
|
+
t.belongs_to :referee, polymorphic: true, null: false
|
6
|
+
t.belongs_to :referral_code
|
7
|
+
|
8
|
+
t.timestamps
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
class CreateReferReferralCodes < ActiveRecord::Migration[7.2]
|
2
|
+
def change
|
3
|
+
create_table :refer_referral_codes do |t|
|
4
|
+
t.belongs_to :referrer, polymorphic: true, null: false
|
5
|
+
t.string :code, null: false, index: { unique: true }
|
6
|
+
|
7
|
+
t.timestamps
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class Refer::ModelGenerator < Rails::Generators::NamedBase
|
2
|
+
source_root File.expand_path("templates", __dir__)
|
3
|
+
|
4
|
+
def migrations
|
5
|
+
rails_command "refer:install:migrations"
|
6
|
+
end
|
7
|
+
|
8
|
+
def add_refer
|
9
|
+
inject_into_class File.join("app", "models", "#{file_path}.rb"), class_name, " has_referrals\n"
|
10
|
+
end
|
11
|
+
end
|
data/lib/refer/engine.rb
CHANGED
data/lib/refer/version.rb
CHANGED
data/lib/refer.rb
CHANGED
@@ -1,6 +1,46 @@
|
|
1
1
|
require "refer/version"
|
2
2
|
require "refer/engine"
|
3
|
+
require "securerandom"
|
3
4
|
|
4
5
|
module Refer
|
5
|
-
|
6
|
+
include ActiveSupport::Configurable
|
7
|
+
|
8
|
+
config_accessor :code_generator, default: ->(referrer) { SecureRandom.alphanumeric(8) }
|
9
|
+
config_accessor :cookie_length, default: 30.days
|
10
|
+
config_accessor :cookie_name, default: :refer_code
|
11
|
+
config_accessor :param_name, default: :ref
|
12
|
+
|
13
|
+
class Error < StandardError; end
|
14
|
+
class AlreadyReferred < Error; end
|
15
|
+
|
16
|
+
def self.referred?(referee)
|
17
|
+
Referral.where(referee: referee).exists?
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.refer(code:, referee:)
|
21
|
+
return if referred?(referee)
|
22
|
+
ReferralCode.find_by(code: code)&.referrals&.create(referee: referee)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.refer!(code:, referee:)
|
26
|
+
raise AlreadyReferred, "#{referee} has already been referred" if referred?(referee)
|
27
|
+
ReferralCode.find_by!(code: code).referrals.create!(referee: referee)
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.cookie(code)
|
31
|
+
{
|
32
|
+
value: code,
|
33
|
+
expires: Refer.cookie_length.from_now
|
34
|
+
}
|
35
|
+
end
|
6
36
|
end
|
37
|
+
|
38
|
+
ActiveSupport.on_load(:active_record) do
|
39
|
+
include Refer::HasReferrals
|
40
|
+
end
|
41
|
+
|
42
|
+
ActiveSupport.on_load(:action_controller) do
|
43
|
+
include Refer::Controller
|
44
|
+
end
|
45
|
+
|
46
|
+
ActiveSupport.run_load_hooks(:refer, Refer)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: refer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Oliver
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-06-
|
11
|
+
date: 2024-06-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -24,7 +24,7 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 6.1.0
|
27
|
-
description: Referral codes for Ruby on Rails
|
27
|
+
description: Referral codes for Ruby on Rails apps
|
28
28
|
email:
|
29
29
|
- excid3@gmail.com
|
30
30
|
executables: []
|
@@ -34,12 +34,21 @@ files:
|
|
34
34
|
- MIT-LICENSE
|
35
35
|
- README.md
|
36
36
|
- Rakefile
|
37
|
-
- app/
|
37
|
+
- app/controllers/concerns/refer/controller.rb
|
38
|
+
- app/models/concerns/refer/has_referrals.rb
|
39
|
+
- app/models/concerns/refer/model.rb
|
40
|
+
- app/models/refer/application_record.rb
|
41
|
+
- app/models/refer/referral.rb
|
42
|
+
- app/models/refer/referral_code.rb
|
38
43
|
- config/routes.rb
|
44
|
+
- db/migrate/20240611180738_create_refer_referrals.rb
|
45
|
+
- db/migrate/20240611183349_create_refer_referral_codes.rb
|
46
|
+
- lib/generators/refer/model/USAGE
|
47
|
+
- lib/generators/refer/model/model_generator.rb
|
39
48
|
- lib/refer.rb
|
40
49
|
- lib/refer/engine.rb
|
41
50
|
- lib/refer/version.rb
|
42
|
-
- lib/tasks/
|
51
|
+
- lib/tasks/refer_tasks.rake
|
43
52
|
homepage: https://github.com/excid3/refer
|
44
53
|
licenses:
|
45
54
|
- MIT
|
@@ -65,5 +74,5 @@ requirements: []
|
|
65
74
|
rubygems_version: 3.5.11
|
66
75
|
signing_key:
|
67
76
|
specification_version: 4
|
68
|
-
summary: Referral codes for Ruby on Rails
|
77
|
+
summary: Referral codes for Ruby on Rails apps
|
69
78
|
test_files: []
|
File without changes
|
File without changes
|