sluggable-rails 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/README.md +81 -5
- data/lib/sluggable/core_ext.rb +3 -3
- data/lib/sluggable/rails/definition.rb +7 -2
- data/lib/sluggable/rails/definitions.rb +2 -2
- data/lib/sluggable/rails/slug.rb +5 -1
- data/lib/sluggable/rails/slugs.rb +1 -1
- data/lib/sluggable/rails/version.rb +1 -1
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 17b9efd9689c4f2a8e4b7e43b9fc548bba77a991783df6ed0c33b17dc7098c0e
|
4
|
+
data.tar.gz: 9e94db4d0cb5ca8397cb60c23a92070757cd5439abb6e0b0b04ba4c14d685ec6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3dfa0e1a89c7ad121fd63aed9ff6dd2dfddcc5e24873a51d8d91e86b73dbf1e07672db0b13285e5c84ea6f4023769f68836a29d039594eb9033ab469c708689f
|
7
|
+
data.tar.gz: 0d32122dd202e54509ec30c199a51fa180c0d3fe732b32b8d3e032b7bbb093785d61da5fe54ed034af00e8148629da611548d3d9b4f34c929a211c81891dab6a
|
data/README.md
CHANGED
@@ -1,4 +1,7 @@
|
|
1
|
-
# Sluggable Rails
|
1
|
+
# Sluggable Rails 🏅
|
2
|
+
[](https://badge.fury.io/rb/sluggable-rails)
|
3
|
+
[](https://codeclimate.com/github/juliendargelos/sluggable-rails/maintainability)
|
4
|
+
|
2
5
|
Provide a unique slug to your records, generated from the attribute of your choice.
|
3
6
|
|
4
7
|
## Usage
|
@@ -16,24 +19,97 @@ Use the `has_slug` method:
|
|
16
19
|
# updated_at :datetime not null
|
17
20
|
#
|
18
21
|
|
19
|
-
class Post <
|
22
|
+
class Post < ApplicationRecord
|
23
|
+
#...
|
24
|
+
|
20
25
|
has_slug by: :title
|
26
|
+
|
27
|
+
#...
|
21
28
|
end
|
22
29
|
```
|
23
30
|
|
31
|
+
```ruby
|
32
|
+
post = Post.create title: 'My first slugified post!'
|
33
|
+
post.slug # "my-first-slugified-post"
|
34
|
+
|
35
|
+
another_post = Post.create title: 'My first slugified post!'
|
36
|
+
another_post.slug # "my-first-slugified-post-1"
|
37
|
+
```
|
38
|
+
|
24
39
|
In this example, the slug will be generated from the post title. By default, it will be stored in the slug attribute.
|
25
40
|
You can choose another attribute to store it:
|
26
41
|
|
27
42
|
```ruby
|
28
|
-
|
43
|
+
class Post < ApplicationRecord
|
44
|
+
#...
|
45
|
+
|
46
|
+
has_slug :custom_attribute, by: :title
|
47
|
+
|
48
|
+
#...
|
49
|
+
end
|
50
|
+
```
|
51
|
+
|
52
|
+
The slug is generated with the [`parameterize` method](http://api.rubyonrails.org/v5.1/classes/ActiveSupport/Inflector.html#method-i-parameterize), you can specify a separator as it expects (default: `'-'`):
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
class Post < ApplicationRecord
|
56
|
+
#...
|
57
|
+
|
58
|
+
has_slug :custom_attribute, by: :title, separator: '_'
|
59
|
+
|
60
|
+
#...
|
61
|
+
```
|
62
|
+
|
63
|
+
Obviously, you have to add the corresponding column to your schema:
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
class CreatePosts < ActiveRecord::Migration[5.1]
|
67
|
+
def change
|
68
|
+
create_table :posts do |t|
|
69
|
+
t.string :title
|
70
|
+
t.string :slug, null: false, index: true, unique: true # Or your custom attribute
|
71
|
+
|
72
|
+
t.timestamps
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
29
76
|
```
|
30
77
|
|
31
|
-
The slug
|
78
|
+
The slug will be automatically generated in order to be unique. And a `presence` and `uniqueness` validations will also be added by the `has_slug` method.
|
79
|
+
|
80
|
+
Moreover, you can define a scope for you slug so its uniqueness will depends on others attributes:
|
32
81
|
|
33
82
|
```ruby
|
34
|
-
|
83
|
+
class Post < ApplicationRecord
|
84
|
+
#...
|
85
|
+
|
86
|
+
belongs_to :user
|
87
|
+
has_slug by: :title, scope: :user_id
|
88
|
+
# You can specify more than one attribute by giving an array of attributes to the scope option.
|
89
|
+
|
90
|
+
#...
|
91
|
+
end
|
35
92
|
```
|
36
93
|
|
94
|
+
In this example, each post will have a slug which is unique for the user it belongs to (but it could be any other attribute).
|
95
|
+
|
96
|
+
The corresponding migration would be:
|
97
|
+
|
98
|
+
```ruby
|
99
|
+
class CreatePosts < ActiveRecord::Migration[5.1]
|
100
|
+
def change
|
101
|
+
create_table :posts do |t|
|
102
|
+
t.string :title
|
103
|
+
t.references :user, foreign_key: true
|
104
|
+
t.string :slug, null: false
|
105
|
+
|
106
|
+
t.timestamps
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
add_index :posts, [:user_id, :slug], unique: true
|
111
|
+
end
|
112
|
+
|
37
113
|
## Installation
|
38
114
|
Add this line to your application's Gemfile:
|
39
115
|
|
data/lib/sluggable/core_ext.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
ActiveRecord::Base.instance_eval do
|
2
2
|
before_save :update_slugs
|
3
3
|
|
4
|
-
def has_slug
|
5
|
-
slug_definitions.add attribute, origin: by, separator: separator
|
6
|
-
validates attribute, presence: true, uniqueness: true
|
4
|
+
def has_slug(attribute = :slug, by:, separator: '-', scope: nil)
|
5
|
+
slug_definitions.add attribute, origin: by, separator: separator, scope: scope
|
6
|
+
validates attribute, presence: true, uniqueness: scope.present? ? { scope: scope } : true
|
7
7
|
end
|
8
8
|
|
9
9
|
def slug_definitions
|
@@ -1,10 +1,11 @@
|
|
1
1
|
class Sluggable::Rails::Definition
|
2
|
-
attr_reader :attribute, :origin, :separator
|
2
|
+
attr_reader :attribute, :origin, :separator, :scope
|
3
3
|
|
4
|
-
def initialize(attribute = :slug, origin:, separator: '-')
|
4
|
+
def initialize(attribute = :slug, origin:, separator: '-', scope: nil)
|
5
5
|
self.attribute = attribute
|
6
6
|
self.origin = origin
|
7
7
|
self.separator = separator
|
8
|
+
self.scope = scope
|
8
9
|
end
|
9
10
|
|
10
11
|
def attribute=(v)
|
@@ -18,4 +19,8 @@ class Sluggable::Rails::Definition
|
|
18
19
|
def separator=(v)
|
19
20
|
@separator = v.to_s
|
20
21
|
end
|
22
|
+
|
23
|
+
def scope=(v)
|
24
|
+
@scope = [v].flatten.map{ |attribute| :"#{attribute}" }.compact.uniq
|
25
|
+
end
|
21
26
|
end
|
@@ -7,11 +7,11 @@ class Sluggable::Rails::Definitions
|
|
7
7
|
@definitions[attribute.to_s.to_sym]
|
8
8
|
end
|
9
9
|
|
10
|
-
def add
|
10
|
+
def add(attribute = :slug, origin:, separator: '-')
|
11
11
|
@definitions[attribute.to_s.to_sym] = Sluggable::Rails::Definition.new attribute, origin: origin, separator: separator
|
12
12
|
end
|
13
13
|
|
14
|
-
def slugs
|
14
|
+
def slugs(from:)
|
15
15
|
slugs = Sluggable::Rails::Slugs.new
|
16
16
|
@definitions.each { |_, definition| slugs.add definition, from }
|
17
17
|
slugs
|
data/lib/sluggable/rails/slug.rb
CHANGED
@@ -50,6 +50,10 @@ class Sluggable::Rails::Slug < String
|
|
50
50
|
undefined? || changed?
|
51
51
|
end
|
52
52
|
|
53
|
+
def scope
|
54
|
+
definition.scope.map{ |attribute| [atribute, record.send(attribute)] }.to_h
|
55
|
+
end
|
56
|
+
|
53
57
|
protected
|
54
58
|
|
55
59
|
def generate
|
@@ -64,7 +68,7 @@ class Sluggable::Rails::Slug < String
|
|
64
68
|
end
|
65
69
|
|
66
70
|
def unique?
|
67
|
-
found = record.class.find_by definition.attribute => self.to_s
|
71
|
+
found = record.class.find_by (definition.attribute => self.to_s).merge(scope)
|
68
72
|
!found || found.id == record.id
|
69
73
|
end
|
70
74
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sluggable-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Julien Dargelos
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-04-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 5.
|
19
|
+
version: 5.2.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 5.
|
26
|
+
version: 5.2.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: sqlite3
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -77,7 +77,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
77
77
|
version: '0'
|
78
78
|
requirements: []
|
79
79
|
rubyforge_project:
|
80
|
-
rubygems_version: 2.
|
80
|
+
rubygems_version: 2.7.3
|
81
81
|
signing_key:
|
82
82
|
specification_version: 4
|
83
83
|
summary: Slugify your rails records.
|