shortener 1.0.1 → 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 +4 -4
- data/.github/workflows/ruby.yml +16 -29
- data/Appraisals +18 -0
- data/{README.rdoc → README.md} +167 -89
- data/app/models/shortener/shortened_url.rb +2 -0
- data/gemfiles/rails_4.2.gemfile +1 -0
- data/gemfiles/rails_5.2.gemfile +1 -0
- data/gemfiles/rails_6.0.gemfile +1 -0
- data/gemfiles/rails_6.1.gemfile +1 -0
- data/gemfiles/rails_7.0.gemfile +7 -0
- data/gemfiles/rails_7.1.gemfile +7 -0
- data/gemfiles/rails_7.2.gemfile +7 -0
- data/gemfiles/rails_8.0.gemfile +7 -0
- data/lib/generators/shortener/shortener_generator.rb +1 -1
- data/lib/shortener/engine.rb +1 -0
- data/lib/shortener/version.rb +1 -1
- data/shortener.gemspec +2 -2
- data/spec/dummy/.gitignore +1 -1
- data/spec/generators/shortener_generator_spec.rb +10 -0
- data/spec/spec_helper.rb +6 -4
- metadata +9 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2a041977450099a1aa8e72195069372424cdf4ad9df7950691225db3e7e07f4d
|
|
4
|
+
data.tar.gz: c9e9910d269d4c6e0c20e1719900d4e43b34e7fc851d151a8363cf31db40e9d7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 358eaf44a89b822bf9fa05c5a334a3d767bdec866def5bf94233e37241c8da9247f419a0bef02e8ee263682d1deda4ee65f0aa696fe2fa10a310fe096567f551
|
|
7
|
+
data.tar.gz: 8a328acff8d9f1f0a110920f1e5589f6bde54c75ad558070afd3a94b5384fb9b41bdc8886b0c2a2dd60e534a7a4a5b3f3bf5fdb1eda926c56a2ff165b48f8b24
|
data/.github/workflows/ruby.yml
CHANGED
|
@@ -10,44 +10,31 @@ jobs:
|
|
|
10
10
|
test:
|
|
11
11
|
runs-on: ubuntu-latest
|
|
12
12
|
strategy:
|
|
13
|
-
fail-fast:
|
|
13
|
+
fail-fast: false
|
|
14
14
|
matrix:
|
|
15
|
-
ruby-version:
|
|
16
|
-
- '
|
|
17
|
-
- '2.7'
|
|
18
|
-
- '3.0'
|
|
15
|
+
ruby-version:
|
|
16
|
+
- '3.1'
|
|
19
17
|
- '3.2'
|
|
18
|
+
- '3.3'
|
|
19
|
+
- '3.4'
|
|
20
20
|
gemfile:
|
|
21
|
-
- rails_4.2.gemfile
|
|
22
|
-
- rails_5.2.gemfile
|
|
23
|
-
- rails_6.0.gemfile
|
|
24
|
-
- rails_6.1.gemfile
|
|
25
21
|
- rails_7.0.gemfile
|
|
22
|
+
- rails_7.1.gemfile
|
|
23
|
+
- rails_7.2.gemfile
|
|
24
|
+
- rails_8.0.gemfile
|
|
26
25
|
include:
|
|
27
26
|
- ruby-version: '2.4'
|
|
28
27
|
gemfile: rails_4.2.gemfile
|
|
29
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
|
|
30
35
|
exclude:
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
- ruby-version: '3.0'
|
|
34
|
-
gemfile: rails_4.2.gemfile
|
|
35
|
-
- ruby-version: '3.2'
|
|
36
|
-
gemfile: rails_4.2.gemfile
|
|
37
|
-
- ruby-version: '3.0'
|
|
38
|
-
gemfile: rails_5.2.gemfile
|
|
39
|
-
- ruby-version: '3.2'
|
|
40
|
-
gemfile: rails_5.2.gemfile
|
|
41
|
-
- ruby-version: '2.4'
|
|
42
|
-
gemfile: rails_6.0.gemfile
|
|
43
|
-
- ruby-version: '3.2'
|
|
44
|
-
gemfile: rails_6.0.gemfile
|
|
45
|
-
- ruby-version: '2.4'
|
|
46
|
-
gemfile: rails_6.1.gemfile
|
|
47
|
-
- ruby-version: '3.2'
|
|
48
|
-
gemfile: rails_6.1.gemfile
|
|
49
|
-
- ruby-version: '2.4'
|
|
50
|
-
gemfile: rails_7.0.gemfile
|
|
36
|
+
- ruby-version: '3.1'
|
|
37
|
+
gemfile: rails_8.0.gemfile
|
|
51
38
|
|
|
52
39
|
env:
|
|
53
40
|
BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/${{ matrix.gemfile }}
|
data/Appraisals
CHANGED
|
@@ -2,20 +2,38 @@ 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
|
+
gem "loofah", "~> 2.20.0"
|
|
5
6
|
end
|
|
6
7
|
|
|
7
8
|
appraise "rails_5.2" do
|
|
8
9
|
gem "rails", "~> 5.2.0"
|
|
10
|
+
gem "loofah", "~> 2.20.0"
|
|
9
11
|
end
|
|
10
12
|
|
|
11
13
|
appraise "rails_6.0" do
|
|
12
14
|
gem "rails", "~> 6.0.0"
|
|
15
|
+
gem 'concurrent-ruby', '1.3.4'
|
|
13
16
|
end
|
|
14
17
|
|
|
15
18
|
appraise "rails_6.1" do
|
|
16
19
|
gem "rails", "~> 6.1.0"
|
|
20
|
+
gem 'concurrent-ruby', '1.3.4'
|
|
17
21
|
end
|
|
18
22
|
|
|
19
23
|
appraise "rails_7.0" do
|
|
20
24
|
gem "rails", "~> 7.0.0"
|
|
25
|
+
gem 'concurrent-ruby', '1.3.4'
|
|
21
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"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
appraise "rails_8.0" do
|
|
37
|
+
gem "rails", "~> 8.0.0"
|
|
38
|
+
end
|
|
39
|
+
|
data/{README.rdoc → README.md}
RENAMED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
[](https://codeclimate.com/github/jpmcgrath/shortener)
|
|
2
|
+
[](https://codeclimate.com/github/jpmcgrath/shortener)
|
|
3
|
+
[](http://badge.fury.io/rb/shortener)
|
|
4
4
|
|
|
5
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
26
|
+
### Upgrading
|
|
27
27
|
|
|
28
|
-
|
|
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
|
-
|
|
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
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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
|
-
|
|
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
|
-
|
|
50
|
-
|
|
51
|
+
```console
|
|
52
|
+
bundle exec rails g migration add_category_to_shortened_url category:string:index
|
|
53
|
+
```
|
|
51
54
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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
|
-
|
|
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
|
-
|
|
71
|
+
## Installation
|
|
67
72
|
|
|
68
73
|
Shortener is compatible with Rails v4, v5, & v6. To install, add to your Gemfile:
|
|
69
74
|
|
|
70
|
-
|
|
75
|
+
```ruby
|
|
76
|
+
gem 'shortener'
|
|
77
|
+
```
|
|
71
78
|
|
|
72
79
|
After you install Shortener run the generator:
|
|
73
80
|
|
|
74
|
-
|
|
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
|
-
|
|
91
|
+
```ruby
|
|
92
|
+
get '/:id' => "shortener/shortened_urls#show"
|
|
93
|
+
```
|
|
83
94
|
|
|
84
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
126
|
+
```ruby
|
|
127
|
+
Shortener.auto_clean_url = true
|
|
128
|
+
```
|
|
108
129
|
|
|
109
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
134
|
-
|
|
135
|
-
|
|
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
|
-
|
|
173
|
+
```ruby
|
|
174
|
+
Shortener::ShortenedUrl.generate("example.com", owner: user)
|
|
140
175
|
|
|
141
|
-
|
|
176
|
+
short_url("http://example.com", owner: user)
|
|
177
|
+
```
|
|
142
178
|
|
|
143
179
|
And to access those URLs:
|
|
144
180
|
|
|
145
|
-
|
|
181
|
+
```ruby
|
|
182
|
+
user.shortened_urls
|
|
183
|
+
```
|
|
146
184
|
|
|
147
|
-
|
|
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
|
-
|
|
191
|
+
```ruby
|
|
192
|
+
Shortener::ShortenedUrl.generate("example.com", owner: user, custom_key: "mykey")
|
|
154
193
|
|
|
155
|
-
|
|
194
|
+
short_url("http://example.com", custom_key: 'yourkey')
|
|
195
|
+
```
|
|
156
196
|
|
|
157
|
-
|
|
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
|
-
|
|
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
|
-
|
|
208
|
+
```ruby
|
|
209
|
+
Shortener::ShortenedUrl.generate("example.com/page", expires_at: 24.hours.since)
|
|
210
|
+
```
|
|
167
211
|
|
|
168
|
-
|
|
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
|
-
|
|
175
|
-
|
|
218
|
+
```ruby
|
|
219
|
+
Shortener::ShortenedUrl.generate("example.com/page", fresh: true)
|
|
220
|
+
short_url("http://example.com", fresh: true)
|
|
221
|
+
```
|
|
176
222
|
|
|
177
|
-
|
|
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
|
-
|
|
228
|
+
```ruby
|
|
229
|
+
Shortener.forbidden_keys.concat %w(terms promo)
|
|
230
|
+
```
|
|
183
231
|
|
|
184
|
-
|
|
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
|
-
|
|
240
|
+
```ruby
|
|
241
|
+
Shortener.ignore_robots = true
|
|
242
|
+
```
|
|
193
243
|
|
|
194
|
-
|
|
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
|
-
|
|
251
|
+
```ruby
|
|
252
|
+
Shortener.subdomain = 's'
|
|
253
|
+
```
|
|
202
254
|
|
|
203
|
-
Within config/routes.rb
|
|
255
|
+
Within `config/routes.rb`
|
|
204
256
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
257
|
+
```ruby
|
|
258
|
+
constraints subdomain: 's' do
|
|
259
|
+
get '/:id' => "shortener/shortened_urls#show"
|
|
260
|
+
end
|
|
261
|
+
```
|
|
208
262
|
|
|
209
|
-
|
|
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
|
-
|
|
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
|
-
|
|
228
|
-
|
|
229
|
-
|
|
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
|
-
|
|
234
|
-
|
|
235
|
-
|
|
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
|
-
|
|
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
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
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
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
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
|
-
|
|
317
|
+
*note:* If no shortened URL is found, the url will be `default_redirect` or `/`
|
|
258
318
|
|
|
259
|
-
|
|
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,7 +328,25 @@ end
|
|
|
268
328
|
|
|
269
329
|
**Note:** Please, replace `dbname` and `dbname_replica` to match your database configuration.
|
|
270
330
|
|
|
271
|
-
|
|
331
|
+
### Configuring Reader and Writer Multi-DB Roles
|
|
332
|
+
|
|
333
|
+
Shortener has one write operation that happens on a GET request. To allow this you can override this method in an initializer.
|
|
334
|
+
|
|
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
|
|
343
|
+
|
|
344
|
+
ActiveSupport.on_load(:shortener_shortened_url) do
|
|
345
|
+
Shortener::ShortenedUrl.prepend(ShortenerWriterMonkeyPatch)
|
|
346
|
+
end
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
## Contributing
|
|
272
350
|
|
|
273
351
|
We welcome new contributors. Because we're all busy people, and because Shortener
|
|
274
352
|
is used/relied upon by many projects, it is essential that new Pull Requests
|
data/gemfiles/rails_4.2.gemfile
CHANGED
data/gemfiles/rails_5.2.gemfile
CHANGED
data/gemfiles/rails_6.0.gemfile
CHANGED
data/gemfiles/rails_6.1.gemfile
CHANGED
data/gemfiles/rails_7.0.gemfile
CHANGED
|
@@ -3,5 +3,12 @@
|
|
|
3
3
|
source "https://rubygems.org"
|
|
4
4
|
|
|
5
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: "../"
|
|
@@ -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)
|
data/lib/shortener/engine.rb
CHANGED
data/lib/shortener/version.rb
CHANGED
data/shortener.gemspec
CHANGED
|
@@ -10,8 +10,8 @@ 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"
|
|
14
|
-
s.homepage = "
|
|
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
17
|
s.add_dependency "voight_kampff", '~> 2.0'
|
data/spec/dummy/.gitignore
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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.
|
|
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:
|
|
12
|
+
date: 2025-10-25 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: voight_kampff
|
|
@@ -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,7 +152,7 @@ files:
|
|
|
153
152
|
- Appraisals
|
|
154
153
|
- Gemfile
|
|
155
154
|
- MIT-LICENSE
|
|
156
|
-
- README.
|
|
155
|
+
- README.md
|
|
157
156
|
- Rakefile
|
|
158
157
|
- app/controllers/shortener/shortened_urls_controller.rb
|
|
159
158
|
- app/helpers/shortener/shortener_helper.rb
|
|
@@ -164,6 +163,9 @@ files:
|
|
|
164
163
|
- gemfiles/rails_6.0.gemfile
|
|
165
164
|
- gemfiles/rails_6.1.gemfile
|
|
166
165
|
- gemfiles/rails_7.0.gemfile
|
|
166
|
+
- gemfiles/rails_7.1.gemfile
|
|
167
|
+
- gemfiles/rails_7.2.gemfile
|
|
168
|
+
- gemfiles/rails_8.0.gemfile
|
|
167
169
|
- lib/generators/shortener/shortener_generator.rb
|
|
168
170
|
- lib/generators/shortener/templates/migration.rb
|
|
169
171
|
- lib/shortener.rb
|
|
@@ -208,12 +210,13 @@ files:
|
|
|
208
210
|
- spec/dummy/public/favicon.ico
|
|
209
211
|
- spec/dummy/script/rails
|
|
210
212
|
- spec/features/shortener_feature_spec.rb
|
|
213
|
+
- spec/generators/shortener_generator_spec.rb
|
|
211
214
|
- spec/helpers/shortener_helper_spec.rb
|
|
212
215
|
- spec/models/shortened_url_spec.rb
|
|
213
216
|
- spec/models/user_spec.rb
|
|
214
217
|
- spec/shortener/shorten_url_interceptor_spec.rb
|
|
215
218
|
- spec/spec_helper.rb
|
|
216
|
-
homepage:
|
|
219
|
+
homepage: https://github.com/jpmcgrath/shortener/
|
|
217
220
|
licenses: []
|
|
218
221
|
metadata: {}
|
|
219
222
|
post_install_message:
|
|
@@ -231,8 +234,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
231
234
|
- !ruby/object:Gem::Version
|
|
232
235
|
version: 2.1.0
|
|
233
236
|
requirements: []
|
|
234
|
-
|
|
235
|
-
rubygems_version: 2.7.6
|
|
237
|
+
rubygems_version: 3.3.27
|
|
236
238
|
signing_key:
|
|
237
239
|
specification_version: 4
|
|
238
240
|
summary: Shortener is a Rails Engine that makes it easy to create shortened URLs for
|