refer 0.2.0 → 0.3.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: 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