caffeinate 2.5.0 → 2.6.1

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: c76dd3d301fbbd11f363162682da9ad258553c6b4608ba399c8cb663db9219cf
4
- data.tar.gz: 0a012afbc96cb06e7950baf8bdd4722693769f88c8f876e9d646580eb2e977f5
3
+ metadata.gz: 768001daf3c0272130745b6749648d136118f4c8a24c2e1b4bca19e77d2883b6
4
+ data.tar.gz: ae9c61c07b543ec15fd3b6e7c7ea09ccdc199c52c54e37f83fc2894717725776
5
5
  SHA512:
6
- metadata.gz: 93962de68a56db6c627c8641018615591db07c324b25f483bc64b19fd247122b32e4f6f895b3c6d1dbdcecca8b96e014f0275fb055e9d3e4fee676a7e43f5294
7
- data.tar.gz: 100043354924dbe03d979384a3e9e51584bf10e9d1f96e9045cabd1d2f4acdf24f763fc003073dad7b3681aa43961aa469d5b6b0a4e5b69472b9bb366dafd665
6
+ metadata.gz: 6311c1a5b9d62542770f7551eff109b7b3f50d6075c8df0462ada136b0f60048da667dcbdf3703a5d847edb5abd0db8ae37cdf38f847ddeb1609d999798dd17f
7
+ data.tar.gz: 943a81a8b7f2a3cefbc4862a8da7c031b00426ec0f4e271eecb0e74b72a6d48e896a3ee9dbb98f64e2363be37a5df7dd57bb8c6f3e2f9f7770e34a25d8127e3e
data/README.md CHANGED
@@ -152,6 +152,19 @@ $ rails g caffeinate:install
152
152
  $ rake db:migrate
153
153
  ```
154
154
 
155
+ Optionally, use different flags for supporting `bigint` or `uuid`:
156
+
157
+ ```bash
158
+ # UUID with pgcrypto (PostgreSQL < 13)
159
+ rails g caffeinate:install --uuid
160
+
161
+ # UUID without pgcrypto (PostgreSQL 13+)
162
+ rails g caffeinate:install --uuid --skip-pgcrypto
163
+
164
+ # Or via primary-key-type
165
+ rails g caffeinate:install --primary-key-type=uuid --skip-pgcrypto
166
+ ```
167
+
155
168
  ### Clean up the business logic
156
169
 
157
170
  Assuming you intend to use Caffeinate to handle emails using ActionMailer, mailers should be responsible for receiving context and creating a `mail` object. Nothing more. (If you are looking for examples that don't use ActionMailer, see [Without ActionMailer](docs/6-without-action-mailer.md).)
@@ -216,7 +229,7 @@ a `Caffeinate::CampaignSubscription`.
216
229
  ```ruby
217
230
  class User < ApplicationRecord
218
231
  after_commit on: :create do
219
- OnboardingDripper.subscribe!(self)
232
+ OnboardingDripper.subscribe(self)
220
233
  end
221
234
  end
222
235
  ```
@@ -8,8 +8,12 @@ module Caffeinate
8
8
 
9
9
  before_action :find_campaign_subscription!
10
10
 
11
+ skip_before_action :verify_authenticity_token, only: [:unsubscribe], if: -> { request.post? }
12
+
11
13
  def unsubscribe
12
14
  @campaign_subscription.unsubscribe!(true)
15
+
16
+ head :ok if request.post?
13
17
  end
14
18
 
15
19
  def subscribe
@@ -27,8 +27,8 @@ module Caffeinate
27
27
  class CampaignSubscription < ApplicationRecord
28
28
  self.table_name = 'caffeinate_campaign_subscriptions'
29
29
 
30
- has_many :caffeinate_mailings, class_name: 'Caffeinate::Mailing', foreign_key: :caffeinate_campaign_subscription_id, dependent: :destroy
31
- has_many :mailings, class_name: 'Caffeinate::Mailing', foreign_key: :caffeinate_campaign_subscription_id, dependent: :destroy
30
+ has_many :caffeinate_mailings, -> { order(send_at: :asc) }, class_name: 'Caffeinate::Mailing', foreign_key: :caffeinate_campaign_subscription_id, dependent: :destroy
31
+ has_many :mailings, -> { order(send_at: :asc) }, class_name: 'Caffeinate::Mailing', foreign_key: :caffeinate_campaign_subscription_id, dependent: :destroy
32
32
  has_many :future_mailings, -> { upcoming.unsent }, class_name: '::Caffeinate::Mailing', foreign_key: :caffeinate_campaign_subscription_id
33
33
 
34
34
  has_one :next_caffeinate_mailing, -> { joins(:caffeinate_campaign_subscription).where(caffeinate_campaign_subscriptions: { ended_at: nil, unsubscribed_at: nil }).upcoming.unsent.order(send_at: :asc) }, class_name: '::Caffeinate::Mailing', foreign_key: :caffeinate_campaign_subscription_id
@@ -38,7 +38,8 @@ module Caffeinate
38
38
  has_one :previous_mailing, -> { sent.order(sent_at: :desc) }, class_name: '::Caffeinate::Mailing', foreign_key: :caffeinate_campaign_subscription_id
39
39
 
40
40
  belongs_to :caffeinate_campaign, class_name: 'Caffeinate::Campaign', foreign_key: :caffeinate_campaign_id
41
- alias_attribute :campaign, :caffeinate_campaign
41
+ alias_method :campaign, :caffeinate_campaign
42
+ alias_method :campaign=, :caffeinate_campaign=
42
43
 
43
44
  belongs_to :subscriber, polymorphic: true
44
45
  belongs_to :user, polymorphic: true, optional: true
@@ -20,9 +20,10 @@ module Caffeinate
20
20
  self.table_name = 'caffeinate_mailings'
21
21
 
22
22
  belongs_to :caffeinate_campaign_subscription, class_name: 'Caffeinate::CampaignSubscription'
23
- alias_attribute :subscription, :caffeinate_campaign_subscription
23
+ alias_method :subscription, :caffeinate_campaign_subscription
24
+ alias_method :subscription=, :caffeinate_campaign_subscription=
24
25
  has_one :caffeinate_campaign, through: :caffeinate_campaign_subscription
25
- alias_attribute :campaign, :caffeinate_campaign
26
+ alias_method :campaign, :caffeinate_campaign
26
27
 
27
28
  scope :upcoming, -> { joins(:caffeinate_campaign_subscription).where(caffeinate_campaign_subscription: ::Caffeinate::CampaignSubscription.active).unsent.unskipped.where('send_at < ?', ::Caffeinate.config.time_now).order('send_at asc') }
28
29
  scope :unsent, -> { unskipped.where(sent_at: nil) }
data/config/routes.rb CHANGED
@@ -3,8 +3,9 @@
3
3
  Caffeinate::Engine.routes.draw do
4
4
  resources :campaign_subscriptions, only: [], param: :token do
5
5
  member do
6
- get :unsubscribe
7
6
  get :subscribe
7
+ get :unsubscribe
8
+ post :unsubscribe
8
9
  end
9
10
  end
10
11
  end
@@ -25,7 +25,7 @@ module Caffeinate
25
25
  # get truncated). This resets the appropriate class-variables between specs
26
26
  def clear_cache!
27
27
  drippers.each do |dripper|
28
- dripper.safe_constantize.class_eval { @caffeinate_campaign = nil }
28
+ dripper.safe_constantize&.instance_variable_set(:@caffeinate_campaign, nil)
29
29
  end
30
30
  end
31
31
 
@@ -12,7 +12,8 @@ module Mail
12
12
  def caffeinate_mailing=(mailing)
13
13
  @caffeinate_mailing = mailing
14
14
  if mailing.is_a?(::Caffeinate::Mailing)
15
- header['List-Unsubscribe'] = "<#{Caffeinate::UrlHelpers.caffeinate_subscribe_url(mailing.subscription)}>"
15
+ header['List-Unsubscribe'] = "<#{Caffeinate::UrlHelpers.caffeinate_unsubscribe_url(mailing.subscription)}>"
16
+ header['List-Unsubscribe-Post'] = 'List-Unsubscribe=One-Click'
16
17
  end
17
18
  end
18
19
 
@@ -1,3 +1,3 @@
1
1
  module Caffeinate
2
- VERSION = "2.5.0"
2
+ VERSION = "2.6.1"
3
3
  end
@@ -8,6 +8,43 @@ module Caffeinate
8
8
 
9
9
  desc 'Creates a Caffeinate initializer and copies migrations to your application.'
10
10
 
11
+ class_option :uuid, type: :boolean, default: false,
12
+ desc: 'Use UUID primary keys'
13
+
14
+ class_option :primary_key_type, type: :string, default: nil,
15
+ desc: 'Primary key type: uuid, bigint, or integer (default)'
16
+
17
+ class_option :skip_pgcrypto, type: :boolean, default: false,
18
+ desc: 'Skip pgcrypto extension (PostgreSQL 13+ has gen_random_uuid built-in)'
19
+
20
+ def primary_key_type
21
+ return :uuid if options[:uuid]
22
+ return options[:primary_key_type].to_sym if options[:primary_key_type]
23
+ nil
24
+ end
25
+
26
+ def primary_key_option
27
+ return '' unless primary_key_type
28
+ ", id: :#{primary_key_type}"
29
+ end
30
+
31
+ def foreign_key_type
32
+ return '' unless primary_key_type
33
+ ", type: :#{primary_key_type}"
34
+ end
35
+
36
+ def column_type_for_polymorphic
37
+ case primary_key_type
38
+ when :uuid then :uuid
39
+ when :bigint then :bigint
40
+ else :integer
41
+ end
42
+ end
43
+
44
+ def enable_pgcrypto?
45
+ primary_key_type == :uuid && !options[:skip_pgcrypto]
46
+ end
47
+
11
48
  # :nodoc:
12
49
  def copy_initializer
13
50
  template 'caffeinate.rb', 'config/initializers/caffeinate.rb'
@@ -4,12 +4,12 @@ class CreateCaffeinateCampaignSubscriptions < ActiveRecord::Migration<%= migrati
4
4
  def change
5
5
  drop_table :caffeinate_campaign_subscriptions if table_exists?(:caffeinate_campaign_subscriptions)
6
6
 
7
- create_table :caffeinate_campaign_subscriptions do |t|
8
- t.references :caffeinate_campaign, null: false, index: { name: :caffeineate_campaign_subscriptions_on_campaign }, foreign_key: true
7
+ create_table :caffeinate_campaign_subscriptions<%= primary_key_option %> do |t|
8
+ t.references :caffeinate_campaign, null: false, index: { name: :caffeineate_campaign_subscriptions_on_campaign }, foreign_key: true<%= foreign_key_type %>
9
9
  t.string :subscriber_type, null: false
10
- t.integer :subscriber_id, null: false
10
+ t.<%= column_type_for_polymorphic %> :subscriber_id, null: false
11
11
  t.string :user_type
12
- t.integer :user_id
12
+ t.<%= column_type_for_polymorphic %> :user_id
13
13
  t.string :token, null: false
14
14
  t.datetime :ended_at
15
15
  t.string :ended_reason
@@ -2,7 +2,11 @@
2
2
 
3
3
  class CreateCaffeinateCampaigns < ActiveRecord::Migration<%= migration_version %>
4
4
  def change
5
- create_table :caffeinate_campaigns do |t|
5
+ <% if enable_pgcrypto? -%>
6
+ enable_extension 'pgcrypto' unless extension_enabled?('pgcrypto')
7
+
8
+ <% end -%>
9
+ create_table :caffeinate_campaigns<%= primary_key_option %> do |t|
6
10
  t.string :name, null: false
7
11
  t.string :slug, null: false
8
12
  t.boolean :active, default: true, null: false
@@ -2,8 +2,8 @@
2
2
 
3
3
  class CreateCaffeinateMailings < ActiveRecord::Migration<%= migration_version %>
4
4
  def change
5
- create_table :caffeinate_mailings do |t|
6
- t.references :caffeinate_campaign_subscription, null: false, foreign_key: true, index: { name: 'index_caffeinate_mailings_on_campaign_subscription' }
5
+ create_table :caffeinate_mailings<%= primary_key_option %> do |t|
6
+ t.references :caffeinate_campaign_subscription, null: false, foreign_key: true, index: { name: 'index_caffeinate_mailings_on_campaign_subscription' }<%= foreign_key_type %>
7
7
  t.datetime :send_at, null: false
8
8
  t.datetime :sent_at
9
9
  t.datetime :skipped_at
metadata CHANGED
@@ -1,17 +1,58 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: caffeinate
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.5.0
4
+ version: 2.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Josh Brody
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2023-08-24 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
- name: rails
13
+ name: activerecord
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: 5.0.0
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: 5.0.0
26
+ - !ruby/object:Gem::Dependency
27
+ name: actionpack
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 5.0.0
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: 5.0.0
40
+ - !ruby/object:Gem::Dependency
41
+ name: actionmailer
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 5.0.0
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: 5.0.0
54
+ - !ruby/object:Gem::Dependency
55
+ name: actionview
15
56
  requirement: !ruby/object:Gem::Requirement
16
57
  requirements:
17
58
  - - ">="
@@ -94,6 +135,20 @@ dependencies:
94
135
  - - ">="
95
136
  - !ruby/object:Gem::Version
96
137
  version: '0'
138
+ - !ruby/object:Gem::Dependency
139
+ name: pg
140
+ requirement: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ type: :development
146
+ prerelease: false
147
+ version_requirements: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
97
152
  - !ruby/object:Gem::Dependency
98
153
  name: sqlite3
99
154
  requirement: !ruby/object:Gem::Requirement
@@ -108,6 +163,20 @@ dependencies:
108
163
  - - ">="
109
164
  - !ruby/object:Gem::Version
110
165
  version: '0'
166
+ - !ruby/object:Gem::Dependency
167
+ name: sprockets-rails
168
+ requirement: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - ">="
171
+ - !ruby/object:Gem::Version
172
+ version: '0'
173
+ type: :development
174
+ prerelease: false
175
+ version_requirements: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - ">="
178
+ - !ruby/object:Gem::Version
179
+ version: '0'
111
180
  - !ruby/object:Gem::Dependency
112
181
  name: timecop
113
182
  requirement: !ruby/object:Gem::Requirement
@@ -213,7 +282,6 @@ homepage: https://github.com/joshmn/caffeinate
213
282
  licenses:
214
283
  - MIT
215
284
  metadata: {}
216
- post_install_message:
217
285
  rdoc_options: []
218
286
  require_paths:
219
287
  - lib
@@ -228,8 +296,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
228
296
  - !ruby/object:Gem::Version
229
297
  version: '0'
230
298
  requirements: []
231
- rubygems_version: 3.1.4
232
- signing_key:
299
+ rubygems_version: 4.0.1
233
300
  specification_version: 4
234
301
  summary: Create, manage, and send scheduled email sequences and drip campaigns from
235
302
  your Rails app.