sluggable-rails 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 524d66a481f56da389dd239d9e1895c11e20740e
4
- data.tar.gz: 5758997da24026a3fa780337259ea7b4315ba6bc
2
+ SHA256:
3
+ metadata.gz: 17b9efd9689c4f2a8e4b7e43b9fc548bba77a991783df6ed0c33b17dc7098c0e
4
+ data.tar.gz: 9e94db4d0cb5ca8397cb60c23a92070757cd5439abb6e0b0b04ba4c14d685ec6
5
5
  SHA512:
6
- metadata.gz: 66477a7d225c4d090f567069bd91974af60e4acc26bb424c16da812ee0bef86afaa54cd1f848408032b2344387108ef8b3e04b2a197b1b315f8eb24dbb670fa7
7
- data.tar.gz: 48a5b48fb9b44e51df0753172db659dd6a215280e370368104d0a1f9ec424b608dd67786c9eae28254f6468c93a029f33fa736a53cc04993fe5ee4019ecc30e9
6
+ metadata.gz: 3dfa0e1a89c7ad121fd63aed9ff6dd2dfddcc5e24873a51d8d91e86b73dbf1e07672db0b13285e5c84ea6f4023769f68836a29d039594eb9033ab469c708689f
7
+ data.tar.gz: 0d32122dd202e54509ec30c199a51fa180c0d3fe732b32b8d3e032b7bbb093785d61da5fe54ed034af00e8148629da611548d3d9b4f34c929a211c81891dab6a
data/README.md CHANGED
@@ -1,4 +1,7 @@
1
- # Sluggable Rails
1
+ # Sluggable Rails 🏅
2
+ [![Gem Version](https://badge.fury.io/rb/sluggable-rails.svg)](https://badge.fury.io/rb/sluggable-rails)
3
+ [![Maintainability](https://api.codeclimate.com/v1/badges/d260555b2cbb561875b4/maintainability)](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 < ActiveRecord::Base
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
- has_slug :custom_attribute, by: :title
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 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 excepts (default: `'-'`):
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
- has_slug :custom_attribute, by: :title, separator: '_'
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
 
@@ -1,9 +1,9 @@
1
1
  ActiveRecord::Base.instance_eval do
2
2
  before_save :update_slugs
3
3
 
4
- def has_slug attribute = :slug, by:, separator: '-'
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 attribute = :slug, origin:, separator: '-'
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 from:
14
+ def slugs(from:)
15
15
  slugs = Sluggable::Rails::Slugs.new
16
16
  @definitions.each { |_, definition| slugs.add definition, from }
17
17
  slugs
@@ -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
@@ -3,7 +3,7 @@ class Sluggable::Rails::Slugs
3
3
  @slugs = []
4
4
  end
5
5
 
6
- def add definition, record
6
+ def add(definition, record)
7
7
  @slugs << Sluggable::Rails::Slug.new(definition, record)
8
8
  end
9
9
 
@@ -1,5 +1,5 @@
1
1
  module Sluggable
2
2
  module Rails
3
- VERSION = '0.1.0'
3
+ VERSION = '0.1.1'
4
4
  end
5
5
  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.0
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: 2017-10-15 00:00:00.000000000 Z
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.1.4
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.1.4
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.6.13
80
+ rubygems_version: 2.7.3
81
81
  signing_key:
82
82
  specification_version: 4
83
83
  summary: Slugify your rails records.