refer 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 624b2aea9ec3f2ea9f987b3ae23e56c96a0f2fa82d42931d98b50e407bc205e3
4
- data.tar.gz: 0f1647e0c4a2f9abb635f754807d12fd47ef7b696114bbd753fc491eca4d6944
3
+ metadata.gz: 736ad28aa8233ae7dd3de16fe4f735931fa626b24f2875d2f60ac0d2791e1c05
4
+ data.tar.gz: c114325825aebd3e62fc5f2a0f29cf8ec7b562b646b2597c326a6631efd5920e
5
5
  SHA512:
6
- metadata.gz: 6c08b0b4c669d9122ab9caf190ab71d7fe1b87621d1b767d5c61a78801e3d3c1785545506cf6c06e06fd55a91f9b1db7e6833731712d9556fcba22a74e5a3a05
7
- data.tar.gz: 14ea41363df007c0ca068538554b19f8a582f6fb3d2b1ba5e0b6cd0e242de5350ced79e84b299f66f6a64a0315c12cf33453241b6d3a9019416b85143957e0df
6
+ metadata.gz: 2929027d9b24206e3ed98c6e6b8858bc5efa9e0df3c094edd272dd80c318f764fe83761a6540d045faf6f9628adf537e94109e4fc88b9108ffb2b71d91fa3969
7
+ data.tar.gz: ab6a96074eba0db0bd0319c4233aae91418a506182dc93ccf6937debd1a8f909a20485fbd238defa6d3ebf261d866554783360d1c16a634c1b25e3330cfce670
data/README.md CHANGED
@@ -1,10 +1,8 @@
1
1
  # Refer
2
- Referral Codes for Ruby on Rails applications.
3
2
 
4
- ## Usage
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
- Or install it yourself as:
17
+ And add Refer to your model:
20
18
  ```bash
21
- $ gem install refer
19
+ bin/rails generate refer:model User
22
20
  ```
23
21
 
24
- ## Contributing
25
- Contribution directions go here.
22
+ ## 🧑‍💻 Usage
26
23
 
27
- ## License
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,11 @@
1
+ module Refer
2
+ module HasReferrals
3
+ extend ActiveSupport::Concern
4
+
5
+ class_methods do
6
+ def has_referrals
7
+ include Refer::Model
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Refer
2
+ module Model
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ has_many :referrals, inverse_of: :referrer, class_name: "Refer::Referral"
7
+ has_one :referral, inverse_of: :referee, class_name: "Refer::Referral"
8
+ delegate :referrer, to: :referral
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,6 @@
1
+ module Refer
2
+ class ApplicationRecord < ActiveRecord::Base
3
+ self.abstract_class = true
4
+ self.table_name_prefix = "refer_"
5
+ end
6
+ 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
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,8 @@
1
+ Description:
2
+ Explain the generator
3
+
4
+ Example:
5
+ bin/rails generate model Thing
6
+
7
+ This will create:
8
+ what/will/it/create
@@ -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
@@ -1,4 +1,5 @@
1
1
  module Refer
2
2
  class Engine < ::Rails::Engine
3
+ isolate_namespace Refer
3
4
  end
4
5
  end
data/lib/refer/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Refer
2
- VERSION = "0.0.1"
2
+ VERSION = "0.1.0"
3
3
  end
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
- # Your code goes here...
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.0.1
4
+ version: 0.1.0
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 00:00:00.000000000 Z
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 applications
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/assets/config/referral_codes_manifest.js
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/referral_codes_tasks.rake
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 applications
77
+ summary: Referral codes for Ruby on Rails apps
69
78
  test_files: []
File without changes