simple_slug 0.3.4 → 0.4.3
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 +5 -5
- data/.gitignore +1 -0
- data/.travis.yml +1 -1
- data/README.md +8 -1
- data/db/migrate/20140113000001_create_simple_slug_history_slug.rb +6 -5
- data/lib/simple_slug.rb +12 -10
- data/lib/simple_slug/adapter.rb +123 -0
- data/lib/simple_slug/history_slug.rb +1 -0
- data/lib/simple_slug/model_addition.rb +24 -121
- data/lib/simple_slug/railtie.rb +0 -2
- data/lib/simple_slug/version.rb +1 -1
- data/simple_slug.gemspec +5 -5
- data/spec/simple_slug/base_spec.rb +5 -5
- data/spec/simple_slug/history_spec.rb +59 -34
- data/spec/simple_slug/model_addition_spec.rb +105 -99
- data/spec/spec_helper.rb +32 -36
- metadata +30 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 355d5d538c1f8ae0da92c5a55c12b61d4920131d68f73bf0cc353fc018b777e1
|
4
|
+
data.tar.gz: 4e9aa08c961ddc1de5811c000b863f191ae3780de257bde157ea3ae7f9ed1d47
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8d44218bf0da7e4119b32e37790e8f866deccc600aae3c6260297bd88fa8557a2fd39f3216a0e7d3a4a29c5a62af551a0bf910480a84bdbcccf6a8868f45500a
|
7
|
+
data.tar.gz: 00f5b303bc4c2384bcb09356f42f93c58786ceefc3e1e15a1ee26eb99e116c58b36e88ef216844379fa53e5a1f4b982a32fc7b3ce56549f0e8ce0e3bd823d4be
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# SimpleSlug
|
2
2
|
|
3
3
|
[](https://travis-ci.org/leschenko/simple_slug)
|
4
|
-
[](https://gemnasium.com/leschenko/simple_slug)
|
5
4
|
|
6
5
|
Simple friendly url generator for ActiveRecord models with history.
|
7
6
|
|
@@ -37,6 +36,14 @@ class User < ActiveRecord::Base
|
|
37
36
|
end
|
38
37
|
```
|
39
38
|
|
39
|
+
Add localization with `slug_YOUR_LOCALE` like columns:
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
class User < ActiveRecord::Base
|
43
|
+
simple_slug :full_name, locales: [nil, :it]
|
44
|
+
end
|
45
|
+
```
|
46
|
+
|
40
47
|
If you want to control when slug is generated, define `should_generate_new_slug?` method:
|
41
48
|
|
42
49
|
```ruby
|
@@ -1,13 +1,14 @@
|
|
1
1
|
class CreateSimpleSlugHistorySlug < ActiveRecord::Migration
|
2
2
|
def change
|
3
|
-
create_table :
|
4
|
-
t.string :slug, null: false
|
3
|
+
create_table :simple_slug_history_slugs do |t|
|
4
|
+
t.string :slug, null: false, limit: 191
|
5
|
+
t.string :locale, limit: 10
|
5
6
|
t.integer :sluggable_id, null: false
|
6
7
|
t.string :sluggable_type, limit: 50, null: false
|
7
|
-
t.
|
8
|
+
t.timestamps
|
8
9
|
end
|
9
10
|
|
10
|
-
add_index :
|
11
|
-
add_index :
|
11
|
+
add_index :simple_slug_history_slugs, :slug
|
12
|
+
add_index :simple_slug_history_slugs, [:sluggable_type, :sluggable_id], name: 'simple_slug_history_slugs_on_sluggable_type_and_sluggable_id'
|
12
13
|
end
|
13
14
|
end
|
data/lib/simple_slug.rb
CHANGED
@@ -4,34 +4,36 @@ require 'simple_slug/model_addition'
|
|
4
4
|
require 'simple_slug/railtie' if Object.const_defined?(:Rails)
|
5
5
|
|
6
6
|
module SimpleSlug
|
7
|
+
autoload :Adapter, 'simple_slug/adapter'
|
8
|
+
autoload :ModelAddition, 'simple_slug/model_addition'
|
7
9
|
autoload :HistorySlug, 'simple_slug/history_slug'
|
8
10
|
|
9
11
|
mattr_accessor :excludes
|
10
|
-
@@excludes = %w(new edit show index session login logout sign_in sign_out users admin stylesheets
|
12
|
+
@@excludes = %w(new edit show index session login logout sign_in sign_out users admin stylesheets javascripts images fonts assets)
|
11
13
|
|
12
14
|
mattr_accessor :slug_regexp
|
13
|
-
@@slug_regexp = /\A
|
15
|
+
@@slug_regexp = /\A(?:\w+[\w\d\-_]*|--\d+)\z/
|
14
16
|
|
15
17
|
mattr_accessor :slug_column
|
16
18
|
@@slug_column = 'slug'
|
17
19
|
|
20
|
+
mattr_accessor :min_length
|
21
|
+
@@min_length = 3
|
22
|
+
|
18
23
|
mattr_accessor :max_length
|
19
|
-
@@max_length =
|
24
|
+
@@max_length = 191
|
20
25
|
|
21
26
|
mattr_accessor :callback_type
|
22
27
|
@@callback_type = :before_validation
|
23
28
|
|
24
|
-
mattr_accessor :
|
25
|
-
@@
|
29
|
+
mattr_accessor :validation
|
30
|
+
@@validation = true
|
26
31
|
|
27
32
|
STARTS_WITH_NUMBER_REGEXP =/\A\d+/
|
28
|
-
|
33
|
+
NUMBER_REGEXP =/\A\d+\z/
|
34
|
+
RESOLVE_SUFFIX_REGEXP = /--\d+\z/
|
29
35
|
|
30
36
|
def self.setup
|
31
37
|
yield self
|
32
38
|
end
|
33
|
-
|
34
|
-
def self.normalize_cyrillic(base)
|
35
|
-
base.tr('АаВЕеіКкМНОоРрСсТуХх', 'AaBEeiKkMHOoPpCcTyXx')
|
36
|
-
end
|
37
39
|
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
module SimpleSlug
|
2
|
+
class Adapter
|
3
|
+
attr_reader :model, :options, :locales
|
4
|
+
attr_accessor :current_locale
|
5
|
+
|
6
|
+
def initialize(model)
|
7
|
+
@model = model
|
8
|
+
@options = model.simple_slug_options
|
9
|
+
@locales = Array(@options[:locales] || [nil])
|
10
|
+
end
|
11
|
+
|
12
|
+
def finder_method
|
13
|
+
options[:history] ? :find_by : :find_by!
|
14
|
+
end
|
15
|
+
|
16
|
+
def valid_locale?(locale)
|
17
|
+
locales.include?(locale)
|
18
|
+
end
|
19
|
+
|
20
|
+
def current_locale
|
21
|
+
valid_locale?(I18n.locale) ? I18n.locale : nil
|
22
|
+
end
|
23
|
+
|
24
|
+
def column_names
|
25
|
+
locales.map{|l| column_name(l) }
|
26
|
+
end
|
27
|
+
|
28
|
+
def column_name(locale=I18n.locale)
|
29
|
+
[options[:slug_column], (locale if valid_locale?(locale))].compact.join('_')
|
30
|
+
end
|
31
|
+
|
32
|
+
def get(record)
|
33
|
+
record.send(column_name)
|
34
|
+
end
|
35
|
+
|
36
|
+
def get_prev(record)
|
37
|
+
record.send("#{column_name}_was")
|
38
|
+
end
|
39
|
+
|
40
|
+
def set(record, value)
|
41
|
+
record.send("#{column_name}=", value)
|
42
|
+
end
|
43
|
+
|
44
|
+
def each_locale
|
45
|
+
locales.each do |l|
|
46
|
+
with_locale(l || I18n.default_locale) { yield }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def reset(record)
|
51
|
+
each_locale{ set record, get_prev(record) }
|
52
|
+
end
|
53
|
+
|
54
|
+
def save_history(record)
|
55
|
+
each_locale do
|
56
|
+
slug_was = record.saved_change_to_attribute(column_name).try!(:first)
|
57
|
+
next if slug_was.blank?
|
58
|
+
::SimpleSlug::HistorySlug.where(sluggable_type: record.class.name, slug: slug_was, locale: current_locale).first_or_initialize.update(sluggable_id: record.id)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def generate(record, force: false)
|
63
|
+
each_locale do
|
64
|
+
next unless force || record.should_generate_new_slug?
|
65
|
+
simple_slug = normalize(slug_base(record))
|
66
|
+
simple_slug = "__#{record.id || rand(9999)}" if simple_slug.blank? && options[:fallback_on_blank]
|
67
|
+
return if simple_slug == get(record).to_s.sub(SimpleSlug::RESOLVE_SUFFIX_REGEXP, '')
|
68
|
+
set(record, resolve(record, simple_slug))
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def normalize(base)
|
73
|
+
parameterize_args = ActiveSupport::VERSION::MAJOR > 4 ? {separator: '-'} : '-'
|
74
|
+
normalized = I18n.transliterate(base).parameterize(**parameterize_args).downcase
|
75
|
+
normalized = "_#{normalized}" if normalized =~ SimpleSlug::STARTS_WITH_NUMBER_REGEXP
|
76
|
+
normalized = normalized[0..options[:max_length].pred] if options[:max_length]
|
77
|
+
normalized
|
78
|
+
end
|
79
|
+
|
80
|
+
def add_suffix(slug_value)
|
81
|
+
"#{slug_value}--#{rand(99999)}"
|
82
|
+
end
|
83
|
+
|
84
|
+
def slug_base(record)
|
85
|
+
options[:slug_method].map{|m| record.send(m).to_s }.reject(&:blank?).join(' ')
|
86
|
+
end
|
87
|
+
|
88
|
+
def resolve(record, slug_value)
|
89
|
+
return slug_value unless slug_exists?(record, slug_value)
|
90
|
+
loop do
|
91
|
+
slug_with_suffix = add_suffix(slug_value)
|
92
|
+
break slug_with_suffix unless slug_exists?(record, slug_with_suffix)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def slug_exists?(record, slug_value)
|
97
|
+
model_slug_exists?(record, slug_value) || history_slug_exists?(record, slug_value)
|
98
|
+
end
|
99
|
+
|
100
|
+
def model_slug_exists?(record, slug_value)
|
101
|
+
base_scope = record.class.unscoped.where(column_name => slug_value)
|
102
|
+
base_scope = base_scope.where('id != ?', record.id) if record.persisted?
|
103
|
+
base_scope.exists?
|
104
|
+
end
|
105
|
+
|
106
|
+
def history_slug_exists?(record, slug_value)
|
107
|
+
return false unless options[:history]
|
108
|
+
base_scope = SimpleSlug::HistorySlug.where(sluggable_type: record.class.name, slug: slug_value)
|
109
|
+
base_scope = base_scope.where('sluggable_id != ?', record.id) if record.persisted?
|
110
|
+
base_scope.exists?
|
111
|
+
end
|
112
|
+
|
113
|
+
def with_locale(locale)
|
114
|
+
if defined? Globalize
|
115
|
+
Globalize.with_locale(locale) do
|
116
|
+
I18n.with_locale(locale) { yield }
|
117
|
+
end
|
118
|
+
else
|
119
|
+
I18n.with_locale(locale) { yield }
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -6,33 +6,35 @@ module SimpleSlug
|
|
6
6
|
|
7
7
|
module SingletonMethods
|
8
8
|
def simple_slug(*args)
|
9
|
-
class_attribute :simple_slug_options, instance_writer: false
|
9
|
+
class_attribute :simple_slug_options, :simple_slug_adapter, instance_writer: false
|
10
10
|
options = args.extract_options!
|
11
11
|
self.simple_slug_options = options.reverse_merge(
|
12
12
|
slug_column: SimpleSlug.slug_column,
|
13
13
|
slug_method: args,
|
14
14
|
slug_regexp: SimpleSlug.slug_regexp,
|
15
|
+
min_length: SimpleSlug.min_length,
|
15
16
|
max_length: SimpleSlug.max_length,
|
16
17
|
callback_type: SimpleSlug.callback_type,
|
17
|
-
|
18
|
+
validation: SimpleSlug.validation
|
18
19
|
)
|
20
|
+
self.simple_slug_adapter = SimpleSlug::Adapter.new(self)
|
19
21
|
|
20
22
|
include InstanceMethods
|
21
23
|
extend ClassMethods
|
22
24
|
|
23
25
|
send(simple_slug_options[:callback_type], :simple_slug_generate, if: :should_generate_new_slug?) if simple_slug_options[:callback_type]
|
24
26
|
|
25
|
-
if simple_slug_options[:
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
27
|
+
if simple_slug_options[:validation]
|
28
|
+
validates *simple_slug_adapter.column_names,
|
29
|
+
presence: true,
|
30
|
+
uniqueness: {case_sensitive: true},
|
31
|
+
exclusion: {in: SimpleSlug.excludes},
|
32
|
+
format: {with: simple_slug_options[:slug_regexp]},
|
33
|
+
length: {minimum: simple_slug_options[:min_length], maximum: simple_slug_options[:max_length]}.reject{|_, v| v.blank? }
|
32
34
|
end
|
33
35
|
|
34
36
|
if simple_slug_options[:history]
|
35
|
-
after_save :
|
37
|
+
after_save :simple_slug_reset, :simple_slug_save_history
|
36
38
|
after_destroy :simple_slug_cleanup_history
|
37
39
|
include InstanceHistoryMethods
|
38
40
|
end
|
@@ -42,144 +44,45 @@ module SimpleSlug
|
|
42
44
|
module ClassMethods
|
43
45
|
def simple_slug_find(id_param)
|
44
46
|
return unless id_param
|
45
|
-
if id_param.is_a?(Integer) || id_param =~
|
47
|
+
if id_param.is_a?(Integer) || id_param =~ SimpleSlug::NUMBER_REGEXP
|
46
48
|
find(id_param)
|
47
49
|
else
|
48
|
-
finder_method
|
49
|
-
send(finder_method, simple_slug_column => id_param) or find(::SimpleSlug::HistorySlug.find_by!(slug: id_param).sluggable_id)
|
50
|
+
send(simple_slug_adapter.finder_method, simple_slug_adapter.column_name => id_param) or simple_slug_history_find(id_param)
|
50
51
|
end
|
51
52
|
end
|
52
53
|
|
53
|
-
|
54
|
-
|
55
|
-
def simple_slug_column(locale=I18n.locale)
|
56
|
-
if simple_slug_localized?(locale)
|
57
|
-
[simple_slug_options[:slug_column], locale].compact.join('_')
|
58
|
-
else
|
59
|
-
simple_slug_options[:slug_column]
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
def simple_slug_columns
|
64
|
-
simple_slug_locales.map{|locale| simple_slug_column(locale) }
|
65
|
-
end
|
66
|
-
|
67
|
-
def simple_slug_locales
|
68
|
-
Array(simple_slug_options[:locales] || [nil])
|
54
|
+
def simple_slug_history_find(slug, locale=I18n.locale)
|
55
|
+
find(SimpleSlug::HistorySlug.find_by!(locale: (locale if simple_slug_adapter.valid_locale?(locale)), slug: slug).sluggable_id)
|
69
56
|
end
|
70
57
|
|
71
|
-
|
72
|
-
return unless locale
|
73
|
-
simple_slug_locales.include?(locale.to_sym)
|
74
|
-
end
|
58
|
+
alias_method :friendly_find, :simple_slug_find
|
75
59
|
end
|
76
60
|
|
77
61
|
module InstanceMethods
|
78
62
|
def to_param
|
79
|
-
|
63
|
+
simple_slug_adapter.get_prev(self).presence || super
|
80
64
|
end
|
81
65
|
|
82
66
|
def should_generate_new_slug?
|
83
|
-
|
84
|
-
return simple_slug_get.blank? unless simple_slug_options[:locales]
|
85
|
-
simple_slug_options[:locales].any? { |locale| simple_slug_get(locale).blank? }
|
67
|
+
simple_slug_adapter.column_names.any?{|cn| send(cn).blank? }
|
86
68
|
end
|
87
69
|
|
88
70
|
def simple_slug_generate(force=false)
|
89
|
-
(
|
90
|
-
simple_slug_generate_for_locale(locale, force)
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
def simple_slug_generate_for_locale(locale=I18n.locale, force=false)
|
95
|
-
simple_slug_with_locale(locale) do
|
96
|
-
simple_slug = simple_slug_normalize(simple_slug_base)
|
97
|
-
simple_slug = simple_slug.first(simple_slug_options[:max_length]) if simple_slug_options[:max_length]
|
98
|
-
return if !force && simple_slug == simple_slug_get(locale).to_s.sub(/--\d+\z/, '')
|
99
|
-
resolved_simple_slug = simple_slug_resolve(simple_slug, locale)
|
100
|
-
simple_slug_set(resolved_simple_slug, locale)
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
def simple_slug_with_locale(locale)
|
105
|
-
if defined? Globalize
|
106
|
-
Globalize.with_locale(locale) do
|
107
|
-
I18n.with_locale(locale) { yield }
|
108
|
-
end
|
109
|
-
else
|
110
|
-
I18n.with_locale(locale) { yield }
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
def simple_slug_base
|
115
|
-
simple_slug_options[:slug_method].map{|m| send(m).to_s }.reject(&:blank?).join(' ')
|
116
|
-
end
|
117
|
-
|
118
|
-
def simple_slug_normalize(base)
|
119
|
-
base = SimpleSlug.normalize_cyrillic(base) unless SimpleSlug::CYRILLIC_LOCALES.include?(I18n.locale)
|
120
|
-
parameterize_args = ActiveSupport::VERSION::MAJOR > 4 ? {separator: '-'} : '-'
|
121
|
-
normalized = I18n.transliterate(base).parameterize(parameterize_args).downcase
|
122
|
-
normalized.to_s =~ SimpleSlug::STARTS_WITH_NUMBER_REGEXP ? "_#{normalized}" : normalized
|
123
|
-
end
|
124
|
-
|
125
|
-
def simple_slug_resolve(slug_value, locale=I18n.locale)
|
126
|
-
if simple_slug_exists?(slug_value, locale)
|
127
|
-
loop do
|
128
|
-
slug_value_with_suffix = simple_slug_next(slug_value)
|
129
|
-
break slug_value_with_suffix unless simple_slug_exists?(slug_value_with_suffix, locale)
|
130
|
-
end
|
131
|
-
else
|
132
|
-
slug_value
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
def simple_slug_next(slug_value)
|
137
|
-
"#{slug_value}--#{rand(99999)}"
|
138
|
-
end
|
139
|
-
|
140
|
-
def simple_slug_exists?(slug_value, locale=I18n.locale)
|
141
|
-
simple_slug_base_exists?(slug_value, locale) || simple_slug_history_exists?(slug_value)
|
142
|
-
end
|
143
|
-
|
144
|
-
def simple_slug_base_exists?(slug_value, locale=I18n.locale)
|
145
|
-
base_scope = self.class.unscoped.where(self.class.simple_slug_column(locale) => slug_value)
|
146
|
-
base_scope = base_scope.where('id != ?', id) if persisted?
|
147
|
-
base_scope.exists?
|
148
|
-
end
|
149
|
-
|
150
|
-
def simple_slug_history_exists?(slug_value)
|
151
|
-
return false unless simple_slug_options[:history]
|
152
|
-
base_scope = ::SimpleSlug::HistorySlug.where(sluggable_type: self.class.name, slug: slug_value)
|
153
|
-
base_scope = base_scope.where('sluggable_id != ?', id) if persisted?
|
154
|
-
base_scope.exists?
|
155
|
-
end
|
156
|
-
|
157
|
-
def simple_slug_set(value, locale=I18n.locale)
|
158
|
-
send "#{self.class.simple_slug_column(locale)}=", value
|
159
|
-
end
|
160
|
-
|
161
|
-
def simple_slug_get(locale=I18n.locale)
|
162
|
-
send self.class.simple_slug_column(locale)
|
163
|
-
end
|
164
|
-
|
165
|
-
def simple_slug_stored_slug(locale=I18n.locale)
|
166
|
-
send("#{self.class.simple_slug_column(locale)}_was")
|
71
|
+
simple_slug_adapter.generate(self, force: force)
|
167
72
|
end
|
168
73
|
end
|
169
74
|
|
170
75
|
module InstanceHistoryMethods
|
171
|
-
def
|
172
|
-
|
173
|
-
simple_slug_set simple_slug_stored_slug
|
76
|
+
def simple_slug_reset
|
77
|
+
errors.blank? || simple_slug_adapter.reset(self)
|
174
78
|
end
|
175
79
|
|
176
80
|
def simple_slug_cleanup_history
|
177
81
|
::SimpleSlug::HistorySlug.where(sluggable_type: self.class.name, sluggable_id: id).delete_all
|
178
82
|
end
|
179
83
|
|
180
|
-
def
|
181
|
-
|
182
|
-
::SimpleSlug::HistorySlug.where(sluggable_type: self.class.name, slug: simple_slug_get).first_or_create{|hs| hs.sluggable_id = id }
|
84
|
+
def simple_slug_save_history
|
85
|
+
simple_slug_adapter.save_history(self)
|
183
86
|
end
|
184
87
|
end
|
185
88
|
end
|
data/lib/simple_slug/railtie.rb
CHANGED
data/lib/simple_slug/version.rb
CHANGED
data/simple_slug.gemspec
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
# coding: utf-8
|
2
1
|
lib = File.expand_path('../lib', __FILE__)
|
3
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
3
|
require 'simple_slug/version'
|
@@ -9,7 +8,7 @@ Gem::Specification.new do |spec|
|
|
9
8
|
spec.authors = ['Alex Leschenko']
|
10
9
|
spec.email = ['leschenko.al@gmail.com']
|
11
10
|
spec.summary = %q{Friendly url generator with history.}
|
12
|
-
spec.description = %q{Simple friendly url generator for ActiveRecord with history.
|
11
|
+
spec.description = %q{Simple friendly url generator for ActiveRecord with history.}
|
13
12
|
spec.homepage = 'https://github.com/leschenko/simple_slug'
|
14
13
|
spec.license = 'MIT'
|
15
14
|
|
@@ -18,10 +17,11 @@ Gem::Specification.new do |spec|
|
|
18
17
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
18
|
spec.require_paths = ['lib']
|
20
19
|
|
21
|
-
spec.add_dependency 'activerecord', '>= 4.0.0', '<
|
22
|
-
spec.add_dependency 'i18n', '~>
|
20
|
+
spec.add_dependency 'activerecord', '>= 4.0.0', '< 6.2'
|
21
|
+
spec.add_dependency 'i18n', '~> 1.8.7'
|
23
22
|
|
24
|
-
spec.add_development_dependency 'bundler'
|
23
|
+
spec.add_development_dependency 'bundler'
|
25
24
|
spec.add_development_dependency 'rake'
|
26
25
|
spec.add_development_dependency 'rspec'
|
26
|
+
spec.add_development_dependency 'sqlite3'
|
27
27
|
end
|
@@ -1,17 +1,17 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe SimpleSlug do
|
4
|
-
|
5
|
-
it '
|
4
|
+
describe 'config' do
|
5
|
+
it 'has column name' do
|
6
6
|
expect(SimpleSlug.slug_column).to eq 'slug'
|
7
7
|
end
|
8
8
|
|
9
|
-
it 'excludes' do
|
9
|
+
it 'has excludes' do
|
10
10
|
expect(SimpleSlug.excludes).to include('new', 'edit')
|
11
11
|
end
|
12
12
|
|
13
|
-
it 'max length' do
|
14
|
-
expect( SimpleSlug.max_length).to eq
|
13
|
+
it 'has max length' do
|
14
|
+
expect( SimpleSlug.max_length).to eq 191
|
15
15
|
end
|
16
16
|
end
|
17
17
|
end
|
@@ -1,54 +1,79 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
class SlugHistoryRspecModel <
|
3
|
+
class SlugHistoryRspecModel < RspecActiveRecordBase
|
4
4
|
simple_slug :name, history: true
|
5
|
+
|
6
|
+
def should_generate_new_slug?
|
7
|
+
true
|
8
|
+
end
|
5
9
|
end
|
6
10
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
+
class SlugLocalizedHistoryRspecModel < RspecActiveRecordBase
|
12
|
+
simple_slug :name_for_slug, history: true, locales: [nil, :en]
|
13
|
+
|
14
|
+
def name_for_slug
|
15
|
+
[name, (I18n.locale unless I18n.locale == I18n.default_locale)].compact.join(' ')
|
16
|
+
end
|
17
|
+
|
18
|
+
def should_generate_new_slug?
|
19
|
+
true
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe 'history' do
|
24
|
+
before :each do
|
25
|
+
RspecActiveRecordBase.delete_all
|
26
|
+
SimpleSlug::HistorySlug.delete_all
|
27
|
+
end
|
28
|
+
|
29
|
+
describe 'persistence' do
|
30
|
+
it 'save previous on change' do
|
31
|
+
sluggable = SlugHistoryRspecModel.create(id: 1, name: 'Hello')
|
32
|
+
expect(SimpleSlug::HistorySlug.where(sluggable_type: 'SlugHistoryRspecModel', sluggable_id: 1).exists?).to be_falsey
|
33
|
+
sluggable.update(name: 'Bye')
|
34
|
+
hs = SimpleSlug::HistorySlug.where(sluggable_type: 'SlugHistoryRspecModel', sluggable_id: 1).to_a
|
35
|
+
expect(hs.size).to eq 1
|
36
|
+
expect(hs.first.locale).to be_falsey
|
37
|
+
expect(hs.first.slug).to eq 'hello'
|
11
38
|
end
|
12
39
|
|
13
|
-
it '
|
14
|
-
|
15
|
-
|
16
|
-
expect
|
17
|
-
SlugHistoryRspecModel.create(id: 1, name: 'Hello')
|
40
|
+
it 'remove on destroy' do
|
41
|
+
sluggable = SlugHistoryRspecModel.create(id: 1, name: 'Hello')
|
42
|
+
sluggable.update(name: 'Bye')
|
43
|
+
expect{ sluggable.destroy }.to change{ SimpleSlug::HistorySlug.where(sluggable_type: 'SlugHistoryRspecModel', sluggable_id: 1).count }.from(1).to(0)
|
18
44
|
end
|
19
45
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
46
|
+
context 'localized' do
|
47
|
+
it 'save previous on change' do
|
48
|
+
SlugLocalizedHistoryRspecModel.create(id: 1, name: 'Hello').update(name: 'Bye')
|
49
|
+
hs = SimpleSlug::HistorySlug.where(sluggable_type: 'SlugLocalizedHistoryRspecModel', sluggable_id: 1).to_a
|
50
|
+
expect(hs.map(&:locale)).to match_array [nil, 'en']
|
51
|
+
expect(hs.map(&:slug)).to match_array %w(hello hello-en)
|
52
|
+
end
|
26
53
|
end
|
27
54
|
end
|
28
55
|
|
29
56
|
describe 'conflicts' do
|
30
|
-
it '
|
31
|
-
|
32
|
-
|
33
|
-
expect(record).to
|
34
|
-
expect(record).to receive(:simple_slug_history_exists?).once.ordered.and_return(false)
|
35
|
-
record.save
|
36
|
-
expect(record.slug).to start_with('hi--')
|
57
|
+
it 'resolve with suffix' do
|
58
|
+
SlugHistoryRspecModel.create(name: 'Hello').update(name: 'Bye')
|
59
|
+
record = SlugHistoryRspecModel.create(name: 'Hello')
|
60
|
+
expect(record.slug).to start_with('hello--')
|
37
61
|
end
|
38
|
-
end
|
39
62
|
|
40
|
-
|
41
|
-
|
42
|
-
|
63
|
+
context 'localized' do
|
64
|
+
it 'resolve with suffix' do
|
65
|
+
SlugLocalizedHistoryRspecModel.create(name: 'Hello').update(name: 'Bye')
|
66
|
+
record = SlugLocalizedHistoryRspecModel.create(name: 'Hello')
|
67
|
+
expect(record.slug).to start_with('hello--')
|
68
|
+
expect(record.slug_en).to start_with('hello-en--')
|
69
|
+
end
|
43
70
|
end
|
71
|
+
end
|
44
72
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
expect(
|
49
|
-
expect(SlugHistoryRspecModel).to receive(:find).with(1).and_return(record)
|
50
|
-
SlugHistoryRspecModel.friendly_find('title')
|
73
|
+
describe 'find' do
|
74
|
+
it 'use history' do
|
75
|
+
SlugLocalizedHistoryRspecModel.create(id: 1, name: 'Hello').update(name: 'Bye')
|
76
|
+
expect(SlugLocalizedHistoryRspecModel.friendly_find('hello')).to be_truthy
|
51
77
|
end
|
52
78
|
end
|
53
|
-
|
54
79
|
end
|
@@ -1,186 +1,192 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
class
|
3
|
+
class SlugRspecModel < RspecActiveRecordBase
|
4
4
|
simple_slug :name
|
5
5
|
end
|
6
6
|
|
7
|
-
class
|
8
|
-
simple_slug :name,
|
7
|
+
class SlugWithFallbackOnBlankRspecModel < RspecActiveRecordBase
|
8
|
+
simple_slug :name, fallback_on_blank: true
|
9
9
|
end
|
10
10
|
|
11
|
-
class
|
12
|
-
simple_slug :name,
|
11
|
+
class SlugWithoutMaxLengthRspecModel < RspecActiveRecordBase
|
12
|
+
simple_slug :name, max_length: nil
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
class SlugWithoutValidationRspecModel < RspecActiveRecordBase
|
17
|
+
simple_slug :name, validation: false
|
13
18
|
end
|
14
19
|
|
15
|
-
class
|
16
|
-
|
17
|
-
|
20
|
+
class SlugWithoutCallbackRspecModel < RspecActiveRecordBase
|
21
|
+
simple_slug :name, callback_type: nil
|
22
|
+
end
|
18
23
|
|
19
|
-
|
24
|
+
class SlugLocalizedRspecModel < RspecActiveRecordBase
|
25
|
+
simple_slug :name_for_slug, history: true, locales: [nil, :en]
|
20
26
|
|
21
|
-
def
|
22
|
-
I18n.locale
|
27
|
+
def name_for_slug
|
28
|
+
[name, (I18n.locale unless I18n.locale == I18n.default_locale)].compact.join(' ')
|
23
29
|
end
|
24
30
|
end
|
25
31
|
|
26
32
|
describe SimpleSlug::ModelAddition do
|
27
|
-
|
28
|
-
|
29
|
-
|
33
|
+
before :each do
|
34
|
+
RspecActiveRecordBase.delete_all
|
35
|
+
SimpleSlug::HistorySlug.delete_all
|
36
|
+
end
|
37
|
+
|
38
|
+
describe 'slug' do
|
39
|
+
it 'generate on save' do
|
40
|
+
expect(SlugRspecModel.create(name: 'Hello').slug).to eq 'hello'
|
30
41
|
end
|
31
42
|
|
32
|
-
it '
|
33
|
-
expect(
|
43
|
+
it 'add prefix for numbers' do
|
44
|
+
expect(SlugRspecModel.create(name: '123').slug).to eq '_123'
|
34
45
|
end
|
35
46
|
|
36
|
-
it '
|
37
|
-
expect(
|
47
|
+
it 'reject excludes' do
|
48
|
+
expect(SlugRspecModel.new(name: 'new')).not_to be_valid
|
38
49
|
end
|
39
50
|
|
40
|
-
it '
|
41
|
-
expect(
|
51
|
+
it 'reject spaces' do
|
52
|
+
expect(SlugRspecModel.new(slug: 'test test')).not_to be_valid
|
42
53
|
end
|
43
54
|
|
44
|
-
it '
|
45
|
-
expect(
|
55
|
+
it 'reject punctuation' do
|
56
|
+
expect(SlugRspecModel.new(slug: 'test.test')).not_to be_valid
|
46
57
|
end
|
47
58
|
|
48
|
-
it '
|
49
|
-
expect(
|
59
|
+
it 'fallback to prefixed id on blank slug source' do
|
60
|
+
expect(SlugWithFallbackOnBlankRspecModel.create({}).slug).to start_with '__'
|
50
61
|
end
|
51
62
|
|
52
|
-
|
53
|
-
|
54
|
-
|
63
|
+
describe '#should_generate_new_slug?' do
|
64
|
+
it 'can omit generation' do
|
65
|
+
allow_any_instance_of(SlugRspecModel).to receive(:should_generate_new_slug?).and_return(false)
|
66
|
+
expect(SlugRspecModel.create(name: 'Hello').slug).to be_blank
|
67
|
+
end
|
55
68
|
end
|
56
69
|
end
|
57
70
|
|
58
|
-
describe '
|
59
|
-
it '
|
60
|
-
|
61
|
-
|
62
|
-
expect(record).to
|
63
|
-
record.save
|
64
|
-
expect(record.slug).to start_with('hi--')
|
71
|
+
describe 'conflicts' do
|
72
|
+
it 'resolve with suffix' do
|
73
|
+
SlugRspecModel.create(name: 'Hello')
|
74
|
+
record = SlugHistoryRspecModel.create(name: 'Hello')
|
75
|
+
expect(record.slug).to start_with('hello--')
|
65
76
|
end
|
66
77
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
78
|
+
context 'localized' do
|
79
|
+
it 'resolve with suffix' do
|
80
|
+
SlugLocalizedRspecModel.create(name: 'Hello')
|
81
|
+
record = SlugLocalizedRspecModel.create(name: 'Hello')
|
82
|
+
expect(record.slug).to start_with('hello--')
|
83
|
+
expect(record.slug_en).to start_with('hello-en--')
|
84
|
+
end
|
72
85
|
end
|
73
86
|
end
|
74
87
|
|
75
88
|
describe '#to_param' do
|
76
89
|
before do
|
77
|
-
allow_any_instance_of(
|
90
|
+
allow_any_instance_of(SlugRspecModel).to receive(:simple_slug_exists?).and_return(false)
|
78
91
|
end
|
79
92
|
|
80
|
-
it 'slug if
|
81
|
-
expect(
|
93
|
+
it 'use slug if present' do
|
94
|
+
expect(SlugRspecModel.create(name: 'Hello').to_param).to eq 'hello'
|
82
95
|
end
|
83
96
|
|
84
|
-
it '
|
85
|
-
expect(
|
97
|
+
it 'do not use unsaved slug' do
|
98
|
+
expect(SlugRspecModel.new(name: 'Hello').to_param).to be_falsey
|
86
99
|
end
|
87
|
-
end
|
88
100
|
|
89
|
-
|
90
|
-
|
91
|
-
expect(SlugGenerationRspecModel).to receive(:find).with(1)
|
92
|
-
SlugGenerationRspecModel.friendly_find(1)
|
101
|
+
it 'use id if slug blank' do
|
102
|
+
expect(SlugRspecModel.create(id: 1).to_param).to eq '1'
|
93
103
|
end
|
104
|
+
end
|
94
105
|
|
95
|
-
|
96
|
-
|
97
|
-
|
106
|
+
describe 'find' do
|
107
|
+
it 'by id on integer like param' do
|
108
|
+
expect(SlugRspecModel).to receive(:find).with('1')
|
109
|
+
SlugRspecModel.friendly_find('1')
|
98
110
|
end
|
99
111
|
|
100
|
-
it '
|
101
|
-
expect(
|
102
|
-
|
112
|
+
it 'by slug' do
|
113
|
+
expect(SlugRspecModel).to receive(:find_by!).with('slug' => 'title').and_return(double)
|
114
|
+
SlugRspecModel.friendly_find('title')
|
103
115
|
end
|
104
116
|
end
|
105
117
|
|
106
118
|
describe 'max length' do
|
107
|
-
before do
|
108
|
-
allow_any_instance_of(SlugGenerationRspecModel).to receive(:simple_slug_exists?).and_return(false)
|
109
|
-
end
|
110
|
-
|
111
|
-
after do
|
112
|
-
SlugGenerationRspecModel.simple_slug_options.delete(:max_length)
|
113
|
-
end
|
114
|
-
|
115
119
|
it 'cuts slug to max length' do
|
116
|
-
record =
|
117
|
-
record.simple_slug_generate
|
118
|
-
expect(record.slug.length).to eq 240
|
119
|
-
end
|
120
|
-
|
121
|
-
it 'use max length from per model options' do
|
122
|
-
SlugGenerationRspecModel.simple_slug_options[:max_length] = 100
|
123
|
-
record = SlugGenerationRspecModel.new(name: 'Hello' * 100)
|
120
|
+
record = SlugRspecModel.new(name: 'Hello' * 100)
|
124
121
|
record.simple_slug_generate
|
125
|
-
expect(record.slug.length).to eq
|
122
|
+
expect(record.slug.length).to eq 191
|
126
123
|
end
|
127
124
|
|
128
|
-
it '
|
129
|
-
|
130
|
-
record = SlugGenerationRspecModel.new(name: 'Hello' * 100)
|
125
|
+
it 'return full slug without max_length option' do
|
126
|
+
record = SlugWithoutMaxLengthRspecModel.new(name: 'Hello' * 100)
|
131
127
|
record.simple_slug_generate
|
132
128
|
expect(record.slug.length).to eq 500
|
133
129
|
end
|
134
130
|
end
|
135
131
|
|
136
|
-
describe '
|
137
|
-
it 'skip
|
138
|
-
expect(
|
132
|
+
describe 'validation' do
|
133
|
+
it 'optionally skip validations' do
|
134
|
+
expect(SlugWithoutValidationRspecModel.validators_on(:slug)).to be_blank
|
139
135
|
end
|
140
136
|
end
|
141
137
|
|
142
|
-
describe '
|
143
|
-
it 'skip callback' do
|
144
|
-
expect(
|
138
|
+
describe 'callbacks' do
|
139
|
+
it 'optionally skip callback' do
|
140
|
+
expect(SlugWithoutCallbackRspecModel.new).not_to receive(:should_generate_new_slug?)
|
145
141
|
end
|
146
142
|
end
|
147
143
|
|
148
144
|
describe 'localized' do
|
149
|
-
before do
|
150
|
-
allow_any_instance_of(SlugGenerationRspecModelLocalized).to receive(:simple_slug_exists?).and_return(false)
|
151
|
-
end
|
152
|
-
|
153
145
|
it 'generate slug for locales' do
|
154
|
-
record =
|
146
|
+
record = SlugLocalizedRspecModel.create(name: 'Hello')
|
155
147
|
expect(record.slug).to eq 'hello'
|
156
148
|
expect(record.slug_en).to eq 'hello-en'
|
157
149
|
end
|
158
150
|
|
151
|
+
describe '#should_generate_new_slug?' do
|
152
|
+
it 'keep slug when present' do
|
153
|
+
record = SlugLocalizedRspecModel.create(name: 'Hello')
|
154
|
+
expect{ record.update(name: 'Bye') }.not_to change{ record.slug }
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'generate slug when blank' do
|
158
|
+
record = SlugLocalizedRspecModel.create(name: 'Hello')
|
159
|
+
record.name = 'bye'
|
160
|
+
record.slug_en = nil
|
161
|
+
expect{ record.save }.to change{ record.slug_en }.to('bye-en')
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
159
165
|
describe '#to_param' do
|
160
|
-
it '
|
161
|
-
record =
|
166
|
+
it 'use unlocalized column for default locale' do
|
167
|
+
record = SlugLocalizedRspecModel.create(name: 'Hello')
|
162
168
|
expect(record.to_param).to eq 'hello'
|
163
169
|
end
|
164
170
|
|
165
|
-
it '
|
166
|
-
record =
|
171
|
+
it 'use localized column for non-default locales' do
|
172
|
+
record = SlugLocalizedRspecModel.create(name: 'Hello')
|
167
173
|
I18n.with_locale(:en) do
|
168
174
|
expect(record.to_param).to eq 'hello-en'
|
169
175
|
end
|
170
176
|
end
|
171
177
|
end
|
172
178
|
|
173
|
-
describe '
|
174
|
-
it 'use default slug column
|
175
|
-
record =
|
176
|
-
expect(
|
177
|
-
SlugGenerationRspecModelLocalized.simple_slug_find('hello')
|
179
|
+
describe 'find' do
|
180
|
+
it 'use default slug column for default locale' do
|
181
|
+
record = SlugLocalizedRspecModel.create(name: 'Hello')
|
182
|
+
expect(SlugLocalizedRspecModel.simple_slug_find('hello')).to eq record
|
178
183
|
end
|
179
184
|
|
180
|
-
it 'use localized slug column' do
|
181
|
-
record =
|
182
|
-
|
183
|
-
|
185
|
+
it 'use localized slug column for non-default locale' do
|
186
|
+
record = SlugLocalizedRspecModel.create(name: 'Hello')
|
187
|
+
I18n.with_locale(:en) do
|
188
|
+
expect(SlugLocalizedRspecModel.simple_slug_find('hello-en')).to eq record
|
189
|
+
end
|
184
190
|
end
|
185
191
|
end
|
186
192
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,48 +1,44 @@
|
|
1
|
+
require 'sqlite3'
|
1
2
|
require 'active_record'
|
2
3
|
require 'i18n'
|
3
4
|
require 'active_support/core_ext'
|
4
5
|
require 'byebug'
|
5
6
|
require 'simple_slug'
|
6
7
|
|
7
|
-
# just silence warning
|
8
8
|
I18n.enforce_available_locales = false
|
9
9
|
I18n.default_locale = :uk
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
true
|
11
|
+
ActiveRecord::Base.establish_connection(
|
12
|
+
adapter: 'sqlite3',
|
13
|
+
database: ':memory:'
|
14
|
+
)
|
15
|
+
|
16
|
+
# ActiveRecord::Base.logger = Logger.new(STDOUT)
|
17
|
+
|
18
|
+
RSpec.configure do |config|
|
19
|
+
config.before(:suite) do
|
20
|
+
ActiveRecord::Migration.verbose = false
|
21
|
+
|
22
|
+
ActiveRecord::Schema.define do
|
23
|
+
create_table :rspec_active_record_bases, force: true do |t|
|
24
|
+
t.string :name
|
25
|
+
t.string :slug, limit: 191
|
26
|
+
t.string :slug_en, limit: 191
|
27
|
+
t.timestamps
|
28
|
+
end
|
29
|
+
|
30
|
+
create_table :simple_slug_history_slugs, force: true do |t|
|
31
|
+
t.string :slug, null: false, limit: 191
|
32
|
+
t.string :locale, limit: 10
|
33
|
+
t.integer :sluggable_id, null: false
|
34
|
+
t.string :sluggable_type, limit: 50, null: false
|
35
|
+
t.timestamps
|
36
|
+
end
|
37
|
+
end
|
39
38
|
end
|
39
|
+
end
|
40
40
|
|
41
|
-
def slug_changed?
|
42
|
-
slug.present?
|
43
|
-
end
|
44
41
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
end
|
42
|
+
class RspecActiveRecordBase < ActiveRecord::Base
|
43
|
+
include SimpleSlug::ModelAddition
|
44
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: simple_slug
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3
|
4
|
+
version: 0.4.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alex Leschenko
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-01-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -19,7 +19,7 @@ dependencies:
|
|
19
19
|
version: 4.0.0
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: '
|
22
|
+
version: '6.2'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -29,35 +29,35 @@ dependencies:
|
|
29
29
|
version: 4.0.0
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: '
|
32
|
+
version: '6.2'
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: i18n
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
36
36
|
requirements:
|
37
37
|
- - "~>"
|
38
38
|
- !ruby/object:Gem::Version
|
39
|
-
version:
|
39
|
+
version: 1.8.7
|
40
40
|
type: :runtime
|
41
41
|
prerelease: false
|
42
42
|
version_requirements: !ruby/object:Gem::Requirement
|
43
43
|
requirements:
|
44
44
|
- - "~>"
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version:
|
46
|
+
version: 1.8.7
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: bundler
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
50
50
|
requirements:
|
51
|
-
- - "
|
51
|
+
- - ">="
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version: '
|
53
|
+
version: '0'
|
54
54
|
type: :development
|
55
55
|
prerelease: false
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
57
|
requirements:
|
58
|
-
- - "
|
58
|
+
- - ">="
|
59
59
|
- !ruby/object:Gem::Version
|
60
|
-
version: '
|
60
|
+
version: '0'
|
61
61
|
- !ruby/object:Gem::Dependency
|
62
62
|
name: rake
|
63
63
|
requirement: !ruby/object:Gem::Requirement
|
@@ -86,7 +86,21 @@ dependencies:
|
|
86
86
|
- - ">="
|
87
87
|
- !ruby/object:Gem::Version
|
88
88
|
version: '0'
|
89
|
-
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
name: sqlite3
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
type: :development
|
97
|
+
prerelease: false
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
description: Simple friendly url generator for ActiveRecord with history.
|
90
104
|
email:
|
91
105
|
- leschenko.al@gmail.com
|
92
106
|
executables: []
|
@@ -101,6 +115,7 @@ files:
|
|
101
115
|
- Rakefile
|
102
116
|
- db/migrate/20140113000001_create_simple_slug_history_slug.rb
|
103
117
|
- lib/simple_slug.rb
|
118
|
+
- lib/simple_slug/adapter.rb
|
104
119
|
- lib/simple_slug/history_slug.rb
|
105
120
|
- lib/simple_slug/model_addition.rb
|
106
121
|
- lib/simple_slug/railtie.rb
|
@@ -114,7 +129,7 @@ homepage: https://github.com/leschenko/simple_slug
|
|
114
129
|
licenses:
|
115
130
|
- MIT
|
116
131
|
metadata: {}
|
117
|
-
post_install_message:
|
132
|
+
post_install_message:
|
118
133
|
rdoc_options: []
|
119
134
|
require_paths:
|
120
135
|
- lib
|
@@ -129,9 +144,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
129
144
|
- !ruby/object:Gem::Version
|
130
145
|
version: '0'
|
131
146
|
requirements: []
|
132
|
-
|
133
|
-
|
134
|
-
signing_key:
|
147
|
+
rubygems_version: 3.0.6
|
148
|
+
signing_key:
|
135
149
|
specification_version: 4
|
136
150
|
summary: Friendly url generator with history.
|
137
151
|
test_files:
|