shortener 1.0.0 → 1.0.2

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: 12594d11b56f84e7c4654bee681887dc084978604ee158c803e384c839b6a937
4
- data.tar.gz: 8550a33e8bd06229cd66c5e9f340ba6cd9c49c77acb5481555b23f43ea659883
3
+ metadata.gz: 2a041977450099a1aa8e72195069372424cdf4ad9df7950691225db3e7e07f4d
4
+ data.tar.gz: c9e9910d269d4c6e0c20e1719900d4e43b34e7fc851d151a8363cf31db40e9d7
5
5
  SHA512:
6
- metadata.gz: 911ad7cc429c015d090760690b53aa5151588f3c384090f293cd608484d0804ba3e72034c97bc31cb99730deabf5c5103045e0ffd89b809dd7c12030b732b57e
7
- data.tar.gz: 8fe1bd76f2a97dc3a9f2b0c1cfe9b4798591f84654f40eb341724df41e1ed6b4f8ae461d54759b2059163e440cf72b81df8246a7a7715cc68cecc57d3279a1c6
6
+ metadata.gz: 358eaf44a89b822bf9fa05c5a334a3d767bdec866def5bf94233e37241c8da9247f419a0bef02e8ee263682d1deda4ee65f0aa696fe2fa10a310fe096567f551
7
+ data.tar.gz: 8a328acff8d9f1f0a110920f1e5589f6bde54c75ad558070afd3a94b5384fb9b41bdc8886b0c2a2dd60e534a7a4a5b3f3bf5fdb1eda926c56a2ff165b48f8b24
@@ -10,52 +10,37 @@ jobs:
10
10
  test:
11
11
  runs-on: ubuntu-latest
12
12
  strategy:
13
- fail-fast: true
13
+ fail-fast: false
14
14
  matrix:
15
- ruby-version:
16
- - '2.4'
17
- - '2.6'
18
- - '2.7'
19
- - '3.0'
15
+ ruby-version:
16
+ - '3.1'
17
+ - '3.2'
18
+ - '3.3'
19
+ - '3.4'
20
20
  gemfile:
21
- - rails_4.gemfile
22
- - rails_5.0.gemfile
23
- - rails_5.1.gemfile
24
- - rails_5.2.gemfile
25
- - rails_6.0.gemfile
26
- - rails_6.1.gemfile
27
21
  - rails_7.0.gemfile
22
+ - rails_7.1.gemfile
23
+ - rails_7.2.gemfile
24
+ - rails_8.0.gemfile
28
25
  include:
29
26
  - ruby-version: '2.4'
30
- gemfile: rails_4.gemfile
27
+ gemfile: rails_4.2.gemfile
31
28
  bundler-version: 1
29
+ - ruby-version: '2.7'
30
+ gemfile: rails_5.2.gemfile
31
+ - ruby-version: '2.7'
32
+ gemfile: rails_6.0.gemfile
33
+ - ruby-version: '3.0'
34
+ gemfile: rails_7.1.gemfile
32
35
  exclude:
33
- - ruby-version: '2.6'
34
- gemfile: rails_4.gemfile
35
- - ruby-version: '2.7'
36
- gemfile: rails_4.gemfile
37
- - ruby-version: '3.0'
38
- gemfile: rails_4.gemfile
39
- - ruby-version: '3.0'
40
- gemfile: rails_5.0.gemfile
41
- - ruby-version: '3.0'
42
- gemfile: rails_5.1.gemfile
43
- - ruby-version: '3.0'
44
- gemfile: rails_5.2.gemfile
45
- - ruby-version: '2.4'
46
- gemfile: rails_6.0.gemfile
47
- - ruby-version: '2.4'
48
- gemfile: rails_6.1.gemfile
49
- - ruby-version: '2.4'
50
- gemfile: rails_7.0.gemfile
51
- - ruby-version: '2.6'
52
- gemfile: rails_7.0.gemfile
36
+ - ruby-version: '3.1'
37
+ gemfile: rails_8.0.gemfile
53
38
 
54
39
  env:
55
40
  BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/${{ matrix.gemfile }}
56
41
 
57
42
  steps:
58
- - uses: actions/checkout@v2
43
+ - uses: actions/checkout@v3
59
44
  - name: Set up Ruby
60
45
  uses: ruby/setup-ruby@v1
61
46
  with:
data/.gitignore CHANGED
@@ -11,6 +11,7 @@ bin/*
11
11
  *.gem
12
12
  *.swp
13
13
  Gemfile.lock
14
+ .ruby-version
14
15
  .rvmrc
15
16
  .redcar/*
16
17
  gemfiles/*.lock
data/Appraisals CHANGED
@@ -1,32 +1,39 @@
1
- appraise "rails_4" do
1
+ appraise "rails_4.2" do
2
2
  gem "rails", "~> 4.2.10"
3
3
  gem "rspec-rails", "~> 3.0"
4
4
  gem "sqlite3", "~> 1.3.6"
5
- end
6
-
7
- appraise "rails_5.0" do
8
- gem "rails", "~> 5.0.7"
9
- gem "rspec-rails", "~> 4.0"
10
- gem "sqlite3", "~> 1.3.6"
11
- end
12
-
13
- appraise "rails_5.1" do
14
- gem "rails", "~> 5.1.6"
15
- gem "rspec-rails", "~> 4.0"
5
+ gem "loofah", "~> 2.20.0"
16
6
  end
17
7
 
18
8
  appraise "rails_5.2" do
19
9
  gem "rails", "~> 5.2.0"
10
+ gem "loofah", "~> 2.20.0"
20
11
  end
21
12
 
22
13
  appraise "rails_6.0" do
23
14
  gem "rails", "~> 6.0.0"
15
+ gem 'concurrent-ruby', '1.3.4'
24
16
  end
25
17
 
26
18
  appraise "rails_6.1" do
27
19
  gem "rails", "~> 6.1.0"
20
+ gem 'concurrent-ruby', '1.3.4'
28
21
  end
29
22
 
30
23
  appraise "rails_7.0" do
31
- gem "rails", "~> 7.0.0.rc1"
24
+ gem "rails", "~> 7.0.0"
25
+ gem 'concurrent-ruby', '1.3.4'
26
+ end
27
+
28
+ appraise "rails_7.1" do
29
+ gem "rails", "~> 7.1.0"
30
+ end
31
+
32
+ appraise "rails_7.2" do
33
+ gem "rails", "~> 7.2.0"
32
34
  end
35
+
36
+ appraise "rails_8.0" do
37
+ gem "rails", "~> 8.0.0"
38
+ end
39
+
@@ -1,12 +1,12 @@
1
- {<img src="https://github.com/jpmcgrath/shortener/actions/workflows/ruby.yml/badge.svg" alt="Build Status" />}[https://github.com/jpmcgrath/shortener/actions]
2
- {<img src="https://codeclimate.com/github/jpmcgrath/shortener/badges/gpa.svg" />}[https://codeclimate.com/github/jpmcgrath/shortener]
3
- {<img src="https://badge.fury.io/rb/shortener.svg" alt="Gem version" />}[http://badge.fury.io/rb/shortener]
1
+ [![Build Status](https://github.com/jpmcgrath/shortener/actions/workflows/ruby.yml/badge.svg)](https://codeclimate.com/github/jpmcgrath/shortener)
2
+ [![Code Climate](https://codeclimate.com/github/jpmcgrath/shortener/badges/gpa.svg)](https://codeclimate.com/github/jpmcgrath/shortener)
3
+ [![Gem version](https://badge.fury.io/rb/shortener.svg)](http://badge.fury.io/rb/shortener)
4
4
 
5
- = Shortener
5
+ # Shortener
6
6
 
7
7
  Shortener is a Rails Engine Gem that makes it easy to create and interpret shortened URLs on your own domain from within your Rails application. Once installed Shortener will generate, store URLS and "unshorten" shortened URLs for your applications visitors, all whilst collecting basic usage metrics.
8
8
 
9
- == Overview
9
+ ## Overview
10
10
 
11
11
  The majority of the Shortener consists of three parts:
12
12
 
@@ -14,64 +14,73 @@ The majority of the Shortener consists of three parts:
14
14
  * a controller to accept incoming requests and redirecting them to the target URL;
15
15
  * a helper for generating shortened URLs from controllers and views.
16
16
 
17
- === Dependencies
17
+ ### Dependencies
18
18
 
19
19
  Shortener is designed to work from within a Ruby on Rail applications. It has dependancies Rails core components like ActiveRecord, ActionController, the rails routing engine and more.
20
20
 
21
- === Ruby Version Support
21
+ ### Ruby Version Support
22
22
 
23
23
  As Ruby 1.9.3 entered end of maintainance in early 2015, the last version of the Shortener gem
24
24
  to support Ruby 1.9.3 is 0.4.x. Shortener v0.5 onwards will require Ruby 2+.
25
25
 
26
- === Upgrading
26
+ ### Upgrading
27
27
 
28
- ==== v0.4.0 to v0.5.0
28
+ #### v0.4.0 to v0.5.0
29
29
  There have been some breaking changes:
30
30
  1. The owner argument is passed into the generator and helper methods as a named parameter.
31
31
  2. Original URLs arguments without a hypertext protocol (http|https) will be assumed to be relative paths.
32
32
 
33
- === v0.5.1 to v0.5.2
33
+ #### v0.5.1 to v0.5.2
34
34
  v0.5.2 introduced the ability to set an expiration date for a shortened URL. The expiration dates
35
35
  are stored in a expires_at column in the database, which can be added to your schema with the following
36
36
  migration:
37
37
 
38
- class AddExpiresAtToShortenedUrl < ActiveRecord::Migration[4.2]
39
- def change
40
- add_column :shortened_urls, :expires_at, :datetime
41
- end
38
+ ```ruby
39
+ class AddExpiresAtToShortenedUrl < ActiveRecord::Migration[4.2]
40
+ def change
41
+ add_column :shortened_urls, :expires_at, :datetime
42
42
  end
43
+ end
44
+ ```
43
45
 
44
- === v0.5.6 to v0.6.1
46
+ #### v0.5.6 to v0.6.1
45
47
  v0.6.1 introduced the ability to categorize a shortened URL. The category value
46
48
  is stored in a string column in the database, which must be added to your schema with the following
47
49
  migration:
48
50
 
49
- bundle exec rails g migration add_category_to_shortened_url category:string:index
50
-
51
+ ```console
52
+ bundle exec rails g migration add_category_to_shortened_url category:string:index
53
+ ```
51
54
 
52
- class AddCategoryToShortenedUrl < ActiveRecord::Migration[4.2]
53
- def change
54
- add_column :shortened_urls, :category, :string
55
- add_index :shortened_urls, :category
56
- end
55
+ ```ruby
56
+ class AddCategoryToShortenedUrl < ActiveRecord::Migration[4.2]
57
+ def change
58
+ add_column :shortened_urls, :category, :string
59
+ add_index :shortened_urls, :category
57
60
  end
61
+ end
62
+ ```
58
63
 
59
- === Some niceities of Shortener:
64
+ ### Some niceities of Shortener:
60
65
 
61
66
  * The controller does a 301 redirect, which is the recommended type of redirect for maintaining maximum google juice to the original URL;
62
67
  * A unique alphanumeric code of generated for each shortened link, this means that we can get more unique combinations than if we just used numbers;
63
68
  * The link records a count of how many times it has been “un-shortened”;
64
69
  * The link can be associated with a user, this allows for stats of the link usage for a particular user and other interesting things;
65
70
 
66
- == Installation
71
+ ## Installation
67
72
 
68
73
  Shortener is compatible with Rails v4, v5, & v6. To install, add to your Gemfile:
69
74
 
70
- gem 'shortener'
75
+ ```ruby
76
+ gem 'shortener'
77
+ ```
71
78
 
72
79
  After you install Shortener run the generator:
73
80
 
74
- rails generate shortener
81
+ ```console
82
+ rails generate shortener
83
+ ```
75
84
 
76
85
  This generator will create a migration to create the shortened_urls table where your shortened URLs will be stored.
77
86
 
@@ -79,109 +88,148 @@ This generator will create a migration to create the shortened_urls table where
79
88
 
80
89
  Then add to your routes:
81
90
 
82
- get '/:id' => "shortener/shortened_urls#show"
91
+ ```ruby
92
+ get '/:id' => "shortener/shortened_urls#show"
93
+ ```
83
94
 
84
- == Configuration
95
+ ## Configuration
85
96
  The gem can be configured in a config/initializers/shortener.rb file.
86
97
 
87
98
  By default, the shortener will generate keys that are 5 characters long. You can change that by specifying the length of the key like so;
88
99
 
89
- Shortener.unique_key_length = 6
100
+ ```ruby
101
+ Shortener.unique_key_length = 6
102
+ ```
90
103
 
91
104
  By default, when a unique key isn't matched the site is redirected to "/". You can change that by specifying a different url like so;
92
105
 
93
- Shortener.default_redirect = "http://www.someurl.com"
106
+ ```ruby
107
+ Shortener.default_redirect = "http://www.someurl.com"
108
+ ```
94
109
 
95
110
  By default, Shortener will generate unique keys using numbers and lowercase a-z. If you desire more combinations, you can enable
96
111
  the upper and lower case charset, by including the following:
97
112
 
98
- Shortener.charset = :alphanumcase
113
+ ```ruby
114
+ Shortener.charset = :alphanumcase
115
+ ```
99
116
 
100
117
  If you want to use a custom charset, you can create your own combination by creating an array of possible values, such as allowing underscore and dashes:
101
118
 
102
- Shortener.charset = ("a".."z").to_a + (0..9).to_a + ["-", "_"]
119
+ ```ruby
120
+ Shortener.charset = ("a".."z").to_a + (0..9).to_a + ["-", "_"]
121
+ ```
103
122
 
104
123
  By default, <b>Shortener assumes URLs to be valid web URLs</b> and normalizes them in an effort to make sure there are no duplicate records generated for effectively same URLs with differences of only non-effective slash etc.
105
124
  You can control this option if it interferes for any of your logic. One common case is for mobile app links or universal links where normalization can corrupt the URLs of form <tt>appname://some_route</tt>
106
125
 
107
- Shortener.auto_clean_url = true
126
+ ```ruby
127
+ Shortener.auto_clean_url = true
128
+ ```
108
129
 
109
- == Usage
130
+ ## Usage
110
131
 
111
132
  To generate a Shortened URL object for the URL "http://example.com" within your controller / models do the following:
112
133
 
113
- Shortener::ShortenedUrl.generate("http://example.com")
134
+ ```ruby
135
+ Shortener::ShortenedUrl.generate("http://example.com")
136
+ ```
114
137
 
115
138
  Alternatively, you can create a shortened url to a relative path within your application:
116
139
 
117
- Shortener::ShortenedUrl.generate("/relative-path?param=whatever")
140
+ ```ruby
141
+ Shortener::ShortenedUrl.generate("/relative-path?param=whatever")
142
+ ```
118
143
 
119
144
  To generate and display a shortened URL in your application use the helper method:
120
145
 
121
- short_url("http://example.com")
146
+ ```ruby
147
+ short_url("http://example.com")
148
+ ```
122
149
 
123
150
  Pass in subdomain, protocol and other options that the UrlHelper url_for accepts:
124
151
 
125
- short_url("http://example.com", url_options: { subdomain: 'foo', host: 'bar', protocol: 'https' } )
152
+ ```ruby
153
+ short_url(
154
+ "http://example.com",
155
+ url_options: { subdomain: 'foo', host: 'bar', protocol: 'https' }
156
+ )
157
+ ```
126
158
 
127
159
  This will generate a shortened URL. store it to the db and return a string representing the shortened URL.
128
160
 
129
- === Shortened URLs with owner
161
+ ### Shortened URLs with owner
130
162
 
131
163
  You can link shortened URLs to an owner, to scope them. To do so, add the following line to the models which will act as owners:
132
164
 
133
- class User < ActiveRecord::Base
134
- has_shortened_urls
135
- end
165
+ ```ruby
166
+ class User < ActiveRecord::Base
167
+ has_shortened_urls
168
+ end
169
+ ```
136
170
 
137
171
  This will allow you to pass the owner when generating URLs:
138
172
 
139
- Shortener::ShortenedUrl.generate("example.com", owner: user)
173
+ ```ruby
174
+ Shortener::ShortenedUrl.generate("example.com", owner: user)
140
175
 
141
- short_url("http://example.com", owner: user)
176
+ short_url("http://example.com", owner: user)
177
+ ```
142
178
 
143
179
  And to access those URLs:
144
180
 
145
- user.shortened_urls
181
+ ```ruby
182
+ user.shortened_urls
183
+ ```
146
184
 
147
- === Shortened URLs with custom unique key
185
+ ### Shortened URLs with custom unique key
148
186
 
149
187
  You can pass in your own key when generating a shortened URL. This should be unique.
150
188
 
151
189
  *Important:* Custom keys can't contain characters other than those defined in *Shortener.charset*. Default is numbers and lowercase a-z (See *Configuration*).
152
190
 
153
- Shortener::ShortenedUrl.generate("example.com", owner: user, custom_key: "mykey")
191
+ ```ruby
192
+ Shortener::ShortenedUrl.generate("example.com", owner: user, custom_key: "mykey")
154
193
 
155
- short_url("http://example.com", custom_key: 'yourkey')
194
+ short_url("http://example.com", custom_key: 'yourkey')
195
+ ```
156
196
 
157
- === Expirable Shortened URLs
197
+ ### Expirable Shortened URLs
158
198
 
159
199
  You can create expirable URLs.
160
200
  Probably, most of the time it would be used with owner:
161
201
 
162
- Shortener::ShortenedUrl.generate("example.com/page", owner: user, expires_at: 24.hours.since)
202
+ ```ruby
203
+ Shortener::ShortenedUrl.generate("example.com/page", owner: user, expires_at: 24.hours.since)
204
+ ```
163
205
 
164
206
  You can omit owner:
165
207
 
166
- Shortener::ShortenedUrl.generate("example.com/page", expires_at: 24.hours.since)
208
+ ```ruby
209
+ Shortener::ShortenedUrl.generate("example.com/page", expires_at: 24.hours.since)
210
+ ```
167
211
 
168
- === Fresh Links
212
+ ### Fresh Links
169
213
 
170
214
  Sometimes you just need that feeling of a fresh, untouched Shortened URL. By default,
171
215
  Shortener will find an existing ShortenedUrl record for a supplied URL. If you want
172
216
  to create a fresh record, you can pass the following argument:
173
217
 
174
- Shortener::ShortenedUrl.generate("example.com/page", fresh: true)
175
- short_url("http://example.com", fresh: true)
218
+ ```ruby
219
+ Shortener::ShortenedUrl.generate("example.com/page", fresh: true)
220
+ short_url("http://example.com", fresh: true)
221
+ ```
176
222
 
177
- === Forbidden keys
223
+ ### Forbidden keys
178
224
 
179
225
  You can ensure that records with forbidden keys will not be generated.
180
226
  In Rails you can put next line into config/initializers/shortener.rb
181
227
 
182
- Shortener.forbidden_keys.concat %w(terms promo)
228
+ ```ruby
229
+ Shortener.forbidden_keys.concat %w(terms promo)
230
+ ```
183
231
 
184
- === Ignoring Robots
232
+ ### Ignoring Robots
185
233
 
186
234
  By default Shortener will count all visits to a shortened url, including any crawler
187
235
  robots like the Google Web Crawler, or Twitter's link unshortening bot. To ignore
@@ -189,24 +237,30 @@ these visits, Shortener makes use of the excellent voight_kampff gem to identify
189
237
  web robots. This feature is disabled by default. To enable add the following to
190
238
  your shortener configuration:
191
239
 
192
- Shortener.ignore_robots = true
240
+ ```ruby
241
+ Shortener.ignore_robots = true
242
+ ```
193
243
 
194
- === Mounting on a Subdomain
244
+ ### Mounting on a Subdomain
195
245
 
196
246
  If you want to constrain the shortener route to a subdomain, the following config will
197
247
  prevent the subdomain parameter from leaking in to shortened URLs if it matches the configured subdomain.
198
248
 
199
- Within config/initializers/shortener.rb
249
+ Within `config/initializers/shortener.rb`
200
250
 
201
- Shortener.subdomain = 's'
251
+ ```ruby
252
+ Shortener.subdomain = 's'
253
+ ```
202
254
 
203
- Within config/routes.rb
255
+ Within `config/routes.rb`
204
256
 
205
- constraints subdomain: 's' do
206
- get '/:id' => "shortener/shortened_urls#show"
207
- end
257
+ ```ruby
258
+ constraints subdomain: 's' do
259
+ get '/:id' => "shortener/shortened_urls#show"
260
+ end
261
+ ```
208
262
 
209
- === URL Parameters
263
+ ### URL Parameters
210
264
 
211
265
  Parameters are passed though from the shortened url, to the destination URL. If the destination
212
266
  URL has the same parameters as the destination URL, the parameters on the shortened url take
@@ -220,43 +274,49 @@ Then, the resulting URL will be:
220
274
  >http://destination.com?test=no&happy=defo&why=not
221
275
  Note how the test parameter takes the value given on the short URL.
222
276
 
223
- === Shorten URLs in generated emails
277
+ ### Shorten URLs in generated emails
224
278
 
225
279
  You can register the included mail interceptor to shorten all links in the emails generated by your Rails app. For example, add to your mailer:
226
280
 
227
- class MyMailer < ActionMailer::Base
228
- register_interceptor Shortener::ShortenUrlInterceptor.new
229
- end
281
+ ```ruby
282
+ class MyMailer < ActionMailer::Base
283
+ register_interceptor Shortener::ShortenUrlInterceptor.new
284
+ end
285
+ ```
230
286
 
231
287
  This will replace all long URLs in the emails generated by MyMailer with shortened versions. The base URL for the shortener will be infered from the mailer's default_url_options. If you use a different hostname for your shortener, you can use:
232
288
 
233
- class MyMailer < ActionMailer::Base
234
- register_interceptor Shortener::ShortenUrlInterceptor.new :base_url => "http://shortener.host"
235
- end
289
+ ```ruby
290
+ class MyMailer < ActionMailer::Base
291
+ register_interceptor Shortener::ShortenUrlInterceptor.new :base_url => "http://shortener.host"
292
+ end
293
+ ```
236
294
 
237
295
  The interceptor supports a few more arguments, see the implementation for details.
238
296
 
239
- === Logging, stats and other tricks
297
+ ### Logging, stats and other tricks
240
298
 
241
299
  If you want more things to happen when a user accesses one of your short urls, you can create your own `show` action as follows:
242
300
 
243
- def show
244
- token = ::Shortener::ShortenedUrl.extract_token(params[:id])
245
- url = ::Shortener::ShortenedUrl.fetch_with_token(token: token, additional_params: params)
246
- # do some logging, store some stats
247
- redirect_to url[:url], status: :moved_permanently
248
- end
301
+ ```ruby
302
+ def show
303
+ token = ::Shortener::ShortenedUrl.extract_token(params[:id])
304
+ url = ::Shortener::ShortenedUrl.fetch_with_token(token: token, additional_params: params)
305
+ # do some logging, store some stats
306
+ redirect_to url[:url], status: :moved_permanently
307
+ end
308
+ ```
249
309
 
250
- === Fetch with Token
251
- The `::Shortener::ShortenedUrl.fetch_with_token(token: token, additional_params: params)` does the following:
252
- 1. finds the ShortenedUrl for the supplied token
253
- 2. increments the use_count for the retrieved ShortenedURL
254
- 3. combines the additional parameters with the URL in the retrieved ShortenedURL
255
- 4. returns a hash of the format `{url: <the original url>, shortened_url: <the retrieved ShortenedURL>}
310
+ ### Fetch with Token
311
+ The `::Shortener::ShortenedUrl.fetch_with_token(token: token, additional_params: params)` does the following:
312
+ 1. finds the ShortenedUrl for the supplied token
313
+ 2. increments the use_count for the retrieved ShortenedURL
314
+ 3. combines the additional parameters with the URL in the retrieved ShortenedURL
315
+ 4. returns a hash of the format `{url: <the original url>, shortened_url: <the retrieved ShortenedURL>}
256
316
 
257
- *note:* If no shortened URL is found, the url will be `default_redirect` or `/`
317
+ *note:* If no shortened URL is found, the url will be `default_redirect` or `/`
258
318
 
259
- === Configuring a different database for shortened_urls table
319
+ ### Configuring a different database for shortened_urls table
260
320
 
261
321
  You can store a `shortened_urls` table in another database and connecting to it by creating a initializer with the following:
262
322
 
@@ -268,26 +328,31 @@ end
268
328
 
269
329
  **Note:** Please, replace `dbname` and `dbname_replica` to match your database configuration.
270
330
 
271
- == Origins
272
-
273
- For a bit of backstory to Shortener see this {blog post}[http://jamespmcgrath.com/a-simple-link-shortener-in-rails/].
331
+ ### Configuring Reader and Writer Multi-DB Roles
274
332
 
275
- == In The Wild
333
+ Shortener has one write operation that happens on a GET request. To allow this you can override this method in an initializer.
276
334
 
277
- Shortener is used in a number of production systems, including, but not limited to:
278
-
279
- - {Doorkeeper - An Event Management Tool}[http://www.doorkeeperhq.com/]
280
- - {1001tweets - Repost your tweets to get more clicks}[http://www.1001tweets.com/]
281
- - {NewsMaker.io - The curated newsletter builder}[https://www.newsmaker.io/]
335
+ ```ruby
336
+ module ShortenerWriterMonkeyPatch
337
+ def increment_usage_count
338
+ ActiveRecord::Base.connected_to(role: :writing) do
339
+ self.class.increment_counter(:use_count, id)
340
+ end
341
+ end
342
+ end
282
343
 
283
- If you are using Shortener in your project and would like to be added to this list, please get in touch!
344
+ ActiveSupport.on_load(:shortener_shortened_url) do
345
+ Shortener::ShortenedUrl.prepend(ShortenerWriterMonkeyPatch)
346
+ end
347
+ ```
284
348
 
285
- == Contributing
349
+ ## Contributing
286
350
 
287
351
  We welcome new contributors. Because we're all busy people, and because Shortener
288
352
  is used/relied upon by many projects, it is essential that new Pull Requests
289
353
  are opened with good spec coverage, and a passing build on supported ruby versions
290
- and Rails versions.
354
+ and Rails versions. Please create a single PR per feature/contribution, with as
355
+ few changes per PR as possible to make it easier to review.
291
356
 
292
357
  To contribute:
293
358
 
@@ -147,3 +147,5 @@ class Shortener::ShortenedUrl < Shortener::Record
147
147
  end
148
148
  end
149
149
  end
150
+
151
+ ActiveSupport.run_load_hooks :shortener_shortened_url, Shortener::ShortenedUrl
@@ -5,5 +5,6 @@ source "https://rubygems.org"
5
5
  gem "rails", "~> 4.2.10"
6
6
  gem "rspec-rails", "~> 3.0"
7
7
  gem "sqlite3", "~> 1.3.6"
8
+ gem "loofah", "~> 2.20.0"
8
9
 
9
10
  gemspec path: "../"
@@ -3,5 +3,6 @@
3
3
  source "https://rubygems.org"
4
4
 
5
5
  gem "rails", "~> 5.2.0"
6
+ gem "loofah", "~> 2.20.0"
6
7
 
7
8
  gemspec path: "../"
@@ -3,5 +3,6 @@
3
3
  source "https://rubygems.org"
4
4
 
5
5
  gem "rails", "~> 6.0.0"
6
+ gem 'concurrent-ruby', '1.3.4'
6
7
 
7
8
  gemspec path: "../"
@@ -3,5 +3,6 @@
3
3
  source "https://rubygems.org"
4
4
 
5
5
  gem "rails", "~> 6.1.0"
6
+ gem 'concurrent-ruby', '1.3.4'
6
7
 
7
8
  gemspec path: "../"
@@ -2,6 +2,13 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "rails", "~> 7.0.0.rc1"
5
+ gem "rails", "~> 7.0.0"
6
+ gem 'concurrent-ruby', '1.3.4'
7
+ gem "sqlite3", "~> 1.4.4"
8
+
9
+ # For Ruby 3.4+ as they transitioned from being Default Gems to Bundled Gems
10
+ gem 'bigdecimal'
11
+ gem 'mutex_m'
12
+ gem 'drb'
6
13
 
7
14
  gemspec path: "../"
@@ -2,7 +2,6 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "rails", "~> 5.1.6"
6
- gem "rspec-rails", "~> 4.0"
5
+ gem "rails", "~> 7.1.0"
7
6
 
8
7
  gemspec path: "../"
@@ -2,8 +2,6 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "rails", "~> 5.0.7"
6
- gem "rspec-rails", "~> 4.0"
7
- gem "sqlite3", "~> 1.3.6"
5
+ gem "rails", "~> 7.2.0"
8
6
 
9
7
  gemspec path: "../"
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rails", "~> 8.0.0"
6
+
7
+ gemspec path: "../"
@@ -9,7 +9,7 @@ class ShortenerGenerator < Rails::Generators::Base
9
9
  end
10
10
 
11
11
  def self.next_migration_number(dirname)
12
- if ActiveRecord::Base.timestamped_migrations
12
+ if ActiveRecord.respond_to?(:timestamped_migrations) ? ActiveRecord.timestamped_migrations : ActiveRecord::Base.timestamped_migrations
13
13
  Time.new.utc.strftime("%Y%m%d%H%M%S")
14
14
  else
15
15
  "%.3d" % (current_migration_number(dirname) + 1)
@@ -1,5 +1,8 @@
1
+ require "rack"
1
2
  require "rails/engine"
3
+ require 'action_dispatch/railtie'
2
4
  require "voight_kampff"
5
+ require "voight_kampff/rails"
3
6
  require "shortener"
4
7
 
5
8
  class Shortener::Engine < ::Rails::Engine #:nodoc:
@@ -1,3 +1,3 @@
1
1
  module Shortener
2
- VERSION = '1.0.0'.freeze
2
+ VERSION = '1.0.2'.freeze
3
3
  end
data/shortener.gemspec CHANGED
@@ -10,11 +10,11 @@ Gem::Specification.new do |s|
10
10
  s.version = Shortener::VERSION
11
11
  s.platform = Gem::Platform::RUBY
12
12
  s.authors = [ "James P. McGrath", "Michael Reinsch" ]
13
- s.email = [ "gems@jamespmcgrath.com", "michael@mobalean.com" ]
14
- s.homepage = "http://jamespmcgrath.com/projects/shortener"
13
+ s.email = [ "gems@jamespmcgrath.com" ]
14
+ s.homepage = "https://github.com/jpmcgrath/shortener/"
15
15
  s.required_rubygems_version = "> 2.1.0"
16
16
 
17
- s.add_dependency "voight_kampff", '~> 1.1.2'
17
+ s.add_dependency "voight_kampff", '~> 2.0'
18
18
 
19
19
  s.add_development_dependency "rails", '>= 3'
20
20
  s.add_development_dependency "sqlite3"
@@ -1 +1 @@
1
- db/*.sqlite3
1
+ db/*.sqlite3*
@@ -0,0 +1,10 @@
1
+ require "spec_helper"
2
+ require File.expand_path("../../../lib/generators/shortener/shortener_generator.rb", __FILE__)
3
+
4
+ RSpec.describe ShortenerGenerator do
5
+ describe ".next_migration_number" do
6
+ it "returns the next migration number" do
7
+ expect { described_class.next_migration_number(".") }.not_to raise_error
8
+ end
9
+ end
10
+ end
data/spec/spec_helper.rb CHANGED
@@ -23,8 +23,10 @@ end
23
23
  migration_path = File.expand_path("../dummy/db/migrate/", __FILE__)
24
24
  if ActiveRecord::Migrator.respond_to?(:migrate)
25
25
  ActiveRecord::Migrator.migrate(migration_path)
26
- elsif Rails::VERSION::MAJOR < 6
27
- ActiveRecord::MigrationContext.new(migration_path).migrate
28
- else
26
+ elsif "#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}" == '6.0'
29
27
  ActiveRecord::MigrationContext.new(migration_path, ActiveRecord::Base.connection.schema_migration).migrate
30
- end
28
+ elsif Rails::VERSION::MAJOR > 6 || (Rails::VERSION::MAJOR == 6 && Rails::VERSION::MINOR >= 1)
29
+ ActiveRecord::MigrationContext.new(migration_path).up
30
+ else
31
+ ActiveRecord::MigrationContext.new(migration_path).migrate
32
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shortener
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - James P. McGrath
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2022-08-12 00:00:00.000000000 Z
12
+ date: 2025-10-25 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: voight_kampff
@@ -17,14 +17,14 @@ dependencies:
17
17
  requirements:
18
18
  - - "~>"
19
19
  - !ruby/object:Gem::Version
20
- version: 1.1.2
20
+ version: '2.0'
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
25
  - - "~>"
26
26
  - !ruby/object:Gem::Version
27
- version: 1.1.2
27
+ version: '2.0'
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: rails
30
30
  requirement: !ruby/object:Gem::Requirement
@@ -143,7 +143,6 @@ description: Shortener is a Rails Engine Gem that makes it easy to create and in
143
143
  visitors, all whilst collecting basic usage metrics.
144
144
  email:
145
145
  - gems@jamespmcgrath.com
146
- - michael@mobalean.com
147
146
  executables: []
148
147
  extensions: []
149
148
  extra_rdoc_files: []
@@ -153,19 +152,20 @@ files:
153
152
  - Appraisals
154
153
  - Gemfile
155
154
  - MIT-LICENSE
156
- - README.rdoc
155
+ - README.md
157
156
  - Rakefile
158
157
  - app/controllers/shortener/shortened_urls_controller.rb
159
158
  - app/helpers/shortener/shortener_helper.rb
160
159
  - app/models/shortener/record.rb
161
160
  - app/models/shortener/shortened_url.rb
162
- - gemfiles/rails_4.gemfile
163
- - gemfiles/rails_5.0.gemfile
164
- - gemfiles/rails_5.1.gemfile
161
+ - gemfiles/rails_4.2.gemfile
165
162
  - gemfiles/rails_5.2.gemfile
166
163
  - gemfiles/rails_6.0.gemfile
167
164
  - gemfiles/rails_6.1.gemfile
168
165
  - gemfiles/rails_7.0.gemfile
166
+ - gemfiles/rails_7.1.gemfile
167
+ - gemfiles/rails_7.2.gemfile
168
+ - gemfiles/rails_8.0.gemfile
169
169
  - lib/generators/shortener/shortener_generator.rb
170
170
  - lib/generators/shortener/templates/migration.rb
171
171
  - lib/shortener.rb
@@ -210,12 +210,13 @@ files:
210
210
  - spec/dummy/public/favicon.ico
211
211
  - spec/dummy/script/rails
212
212
  - spec/features/shortener_feature_spec.rb
213
+ - spec/generators/shortener_generator_spec.rb
213
214
  - spec/helpers/shortener_helper_spec.rb
214
215
  - spec/models/shortened_url_spec.rb
215
216
  - spec/models/user_spec.rb
216
217
  - spec/shortener/shorten_url_interceptor_spec.rb
217
218
  - spec/spec_helper.rb
218
- homepage: http://jamespmcgrath.com/projects/shortener
219
+ homepage: https://github.com/jpmcgrath/shortener/
219
220
  licenses: []
220
221
  metadata: {}
221
222
  post_install_message:
@@ -233,8 +234,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
233
234
  - !ruby/object:Gem::Version
234
235
  version: 2.1.0
235
236
  requirements: []
236
- rubyforge_project:
237
- rubygems_version: 2.7.6
237
+ rubygems_version: 3.3.27
238
238
  signing_key:
239
239
  specification_version: 4
240
240
  summary: Shortener is a Rails Engine that makes it easy to create shortened URLs for