refer 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d3e23e2268de377fc2bf73d90fc5ede044f1a31cd37f748e925ca68f11fcb059
4
- data.tar.gz: 27ae4e3b9d7cca116132bcc3fb5310c6a7b82352d2330f70b52b5004c76838cf
3
+ metadata.gz: 8c8a0abb5e281f32bf502b1de5c76ce89d8f39414a5e03b5f499339a6d253fee
4
+ data.tar.gz: 1c2a9895ad6841fcef7511c6dc3d591ead6ad944ffdd32b15327541204ab3a7b
5
5
  SHA512:
6
- metadata.gz: ee9e1dae466166dd4299e39ede4e06ea492c21c03f21ea0f4f13fc8343a1eca039c8e6d2914fbf35e8ea4354b8dda9a04057699361db91ad45e56d896e98ac6a
7
- data.tar.gz: 0e5b8663f94465cc9ce236310f1b728f011d442f8076f6184cd7a0bb5a2480bbd81205c0ecc5a5bc81dbe611e30c672a6f7015bb0153233c3c70c98def454238
6
+ metadata.gz: 5dafc7f167fbdaa7de09c830a1fc37384e3c775bc12daa0e95a3bcd01b753869c558c95148b5dfe76e56ef94ded5df5a9ad554ee8e8250d90be9c2cc6e3875c2
7
+ data.tar.gz: 5b6cdb88cad2df78e0cfc63a31389b6dd4fda8e06d82acd7ad9ddd0dd844038f5d0c1918b536972528b858260e7fa61645f0935e54ba84044b48a12f37b1e70b
data/README.md CHANGED
@@ -139,6 +139,27 @@ To access a user's referrer, you can use `referrer`:
139
139
  ```ruby
140
140
  user.referrer #=> User that referred this User
141
141
  ```
142
+ ## Refer with Devise
143
+
144
+ To use Refer with Devise, you'll need to customize the Devise controller to track the referral after a successful registration.
145
+
146
+ We can do this by telling Devise to use a custom controller in the routes and hooking into the `create` action to track the referral.
147
+
148
+ ```ruby
149
+ # config/routes.rb
150
+ devise_for :users, controllers: { registrations: "users/registrations" }
151
+ ```
152
+
153
+ ```ruby
154
+ # app/controllers/users/registrations_controller.rb
155
+ class Users::RegistrationsController < Devise::RegistrationsController
156
+ def create
157
+ super do
158
+ refer resource if resource.persisted?
159
+ end
160
+ end
161
+ end
162
+ ```
142
163
 
143
164
  ## Providing Referral Rewards
144
165
 
@@ -15,9 +15,11 @@ module Refer
15
15
  private
16
16
 
17
17
  def set_refer_cookie(param_name: Refer.param_name, cookie_name: Refer.cookie_name)
18
- if (code = params[param_name])
19
- cookies[cookie_name] = Refer.cookie(code)
20
- end
18
+ code = params[param_name]
19
+ return if code.blank?
20
+
21
+ cookies[cookie_name] = Refer.cookie(code) if Refer.overwrite_cookie || cookies[cookie_name].blank?
22
+ ReferralCode.find_by(code: code)&.track_visit(request) if Refer.track_visits
21
23
  end
22
24
  end
23
25
  end
@@ -2,10 +2,14 @@ module Refer
2
2
  class Referral < ApplicationRecord
3
3
  belongs_to :referrer, polymorphic: true
4
4
  belongs_to :referee, polymorphic: true
5
- belongs_to :referral_code, optional: true
5
+ belongs_to :referral_code, optional: true, counter_cache: true
6
6
 
7
7
  before_validation do
8
8
  self.referrer = referral_code&.referrer
9
9
  end
10
+
11
+ def complete!(**attributes)
12
+ update attributes.with_defaults(completed_at: Time.current)
13
+ end
10
14
  end
11
15
  end
@@ -2,15 +2,20 @@ module Refer
2
2
  class ReferralCode < ApplicationRecord
3
3
  belongs_to :referrer, polymorphic: true
4
4
  has_many :referrals, dependent: :nullify
5
+ has_many :visits, dependent: :delete_all
5
6
 
6
7
  validates :code, presence: true, uniqueness: true
7
8
 
8
- before_create if: -> { Refer.code_generator } do
9
- Refer.code_generator.call(referrer)
9
+ before_validation if: -> { Refer.code_generator } do
10
+ self.code = Refer.code_generator.call(referrer)
10
11
  end
11
12
 
12
13
  def to_param
13
14
  code
14
15
  end
16
+
17
+ def track_visit(request)
18
+ visits.from_request(request).save
19
+ end
15
20
  end
16
21
  end
@@ -0,0 +1,16 @@
1
+ module Refer
2
+ class Visit < ApplicationRecord
3
+ belongs_to :referral_code, counter_cache: true
4
+
5
+ normalizes :ip, with: -> { Refer.mask_ip(_1) }
6
+
7
+ def self.from_request(request)
8
+ new(
9
+ ip: request.ip,
10
+ user_agent: request.user_agent,
11
+ referrer: request.referrer,
12
+ referring_domain: (URI.parse(request.referrer).try(:host) rescue nil)
13
+ )
14
+ end
15
+ end
16
+ end
@@ -1,4 +1,4 @@
1
- class CreateReferReferrals < ActiveRecord::Migration[7.2]
1
+ class CreateReferReferrals < ActiveRecord::Migration[6.1]
2
2
  def change
3
3
  create_table :refer_referrals do |t|
4
4
  t.belongs_to :referrer, polymorphic: true, null: false
@@ -1,4 +1,4 @@
1
- class CreateReferReferralCodes < ActiveRecord::Migration[7.2]
1
+ class CreateReferReferralCodes < ActiveRecord::Migration[6.1]
2
2
  def change
3
3
  create_table :refer_referral_codes do |t|
4
4
  t.belongs_to :referrer, polymorphic: true, null: false
@@ -0,0 +1,17 @@
1
+ class CreateReferVisits < ActiveRecord::Migration[7.2]
2
+ def change
3
+ create_table :refer_visits do |t|
4
+ t.belongs_to :referral_code, null: false, foreign_key: { to_table: :refer_referral_codes }
5
+ t.string :ip
6
+ t.text :user_agent
7
+ t.text :referrer
8
+ t.string :referring_domain
9
+
10
+ t.timestamps
11
+ end
12
+
13
+ add_column :refer_referral_codes, :referrals_count, :integer, default: 0
14
+ add_column :refer_referral_codes, :visits_count, :integer, default: 0
15
+ add_column :refer_referrals, :completed_at, :datetime
16
+ end
17
+ end
data/lib/refer/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Refer
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
data/lib/refer.rb CHANGED
@@ -9,6 +9,9 @@ module Refer
9
9
  config_accessor :cookie_length, default: 30.days
10
10
  config_accessor :cookie_name, default: :refer_code
11
11
  config_accessor :param_name, default: :ref
12
+ config_accessor :overwrite_cookie, default: true
13
+ config_accessor :track_visits, default: true
14
+ config_accessor :mask_ips, default: true
12
15
 
13
16
  class Error < StandardError; end
14
17
  class AlreadyReferred < Error; end
@@ -33,6 +36,20 @@ module Refer
33
36
  expires: Refer.cookie_length.from_now
34
37
  }
35
38
  end
39
+
40
+ # From Ahoy gem: https://github.com/ankane/ahoy/blob/v5.1.0/lib/ahoy.rb#L133-L142
41
+ def self.mask_ip(ip)
42
+ return ip unless mask_ips
43
+
44
+ addr = IPAddr.new(ip)
45
+ if addr.ipv4?
46
+ # set last octet to 0
47
+ addr.mask(24).to_s
48
+ else
49
+ # set last 80 bits to zeros
50
+ addr.mask(48).to_s
51
+ end
52
+ end
36
53
  end
37
54
 
38
55
  ActiveSupport.on_load(:active_record) do
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.2.0
4
+ version: 0.3.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-12 00:00:00.000000000 Z
11
+ date: 2024-07-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -40,9 +40,11 @@ files:
40
40
  - app/models/refer/application_record.rb
41
41
  - app/models/refer/referral.rb
42
42
  - app/models/refer/referral_code.rb
43
+ - app/models/refer/visit.rb
43
44
  - config/routes.rb
44
45
  - db/migrate/20240611180738_create_refer_referrals.rb
45
46
  - db/migrate/20240611183349_create_refer_referral_codes.rb
47
+ - db/migrate/20240701172643_create_refer_visits.rb
46
48
  - lib/generators/refer/install/USAGE
47
49
  - lib/generators/refer/install/install_generator.rb
48
50
  - lib/generators/refer/model/USAGE
@@ -73,7 +75,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
73
75
  - !ruby/object:Gem::Version
74
76
  version: '0'
75
77
  requirements: []
76
- rubygems_version: 3.5.11
78
+ rubygems_version: 3.5.13
77
79
  signing_key:
78
80
  specification_version: 4
79
81
  summary: Referral codes & affiliate links for Ruby on Rails apps