refer 0.2.1 → 0.4.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: c2b67d5a90aba044db91c58de5ba63120d31b89e4826545e3589388eae68922a
4
- data.tar.gz: bccf49ec61313f94f7cf842920249d0af40bda63dd632fef70694701912b1e63
3
+ metadata.gz: 1c0b4ef5d6babacbd720f0b0b8ec807d09b5073e26f059978b75ef183e437962
4
+ data.tar.gz: 46e08c8caee9dc594535199dac39c55cae05d0dc7b253d9e2918ac9a0fbae201
5
5
  SHA512:
6
- metadata.gz: d96dbd8d446574bf29433a558f9b342e385a0af450d2885d37db182960ef3cb1a1fe38d7be0f9eeac7ace6eeb77b7d7117c30f606eb220726764ed6b95ea7b45
7
- data.tar.gz: 597c07e84d93b9b6ad2d487a61ad456c20f0b4e687a8fe5b2b6e5184327e11ae79b68b7426acb7d266d047b2b6259d4c9d8f3e583e6f4e97e17ea6ca630028b7
6
+ metadata.gz: f45a3afc36d2965410d65d47a0b9c3b216ee51f2008a0b4c0836e7236e36d3a949452f31c8aa64be31f2d9073e6eef3138f3e6ca014b3699e7ea2c9984176447
7
+ data.tar.gz: 98f214d7321441fdc95b9e01207e0a4aff73435d11b032b28adb40ac20254a3d759f88288e6faa61477ff85014e5374911a922c1e988fef219f9e60a45a3d3d7
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,16 @@ 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
+
7
+ scope :completed, -> { where.not(completed_at: nil) }
6
8
 
7
9
  before_validation do
8
10
  self.referrer = referral_code&.referrer
9
11
  end
12
+
13
+ def complete!(**attributes)
14
+ update attributes.with_defaults(completed_at: Time.current)
15
+ end
10
16
  end
11
17
  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
@@ -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.1"
2
+ VERSION = "0.4.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.1
4
+ version: 0.4.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-17 00:00:00.000000000 Z
11
+ date: 2024-07-17 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.13
78
+ rubygems_version: 3.5.14
77
79
  signing_key:
78
80
  specification_version: 4
79
81
  summary: Referral codes & affiliate links for Ruby on Rails apps