acts_as_permalink 0.6.0 → 1.0.0

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
  SHA1:
3
- metadata.gz: 4633aa91665c5b810b32f1c2e748674d74c5d66c
4
- data.tar.gz: e06d13bcdb3f1a032b71ff1659b391eb5dedb945
3
+ metadata.gz: a688f2777a3102e366b6caa9c9b4a820dcbe1dbd
4
+ data.tar.gz: aa13d167b062e6aa5d68c81e717fe2be53dc7b33
5
5
  SHA512:
6
- metadata.gz: 663b5f0f6df7dd2527a32b17f090118a0213c8c280db92bc5abfd5c2cce23b06bd1fe73fdf49c830135775117369509cf727710cfea9e09b39cb2f793921f0e7
7
- data.tar.gz: 20c6178a41efd0379dff74a4f3151f7116e06593cb9ada693253ef0c91b4a0589431cc4d5ed4f7ee37b8ea3d9c05b6422df553e3fb7c627187672ce1227165c2
6
+ metadata.gz: 5dfcbb6895a593a348402b31cfae60bc08df806b55285110c9b239434ea16aac07297ce20c5592365a7ad009544c1e5c6ac53c7e1e29026160cebca9943ad385
7
+ data.tar.gz: 214c634039408be7bbb7b1751a7f894f1358687f69f32c96593526461db0e1b8feae1bd624110ad93d358ad8e8e22b74a86fadfb64db14f63365db843de86585
@@ -21,6 +21,12 @@ Or stand alone:
21
21
  $ gem install acts_as_permalink
22
22
  ```
23
23
 
24
+ ## Requirements
25
+
26
+ * Ruby 2.0 or higher
27
+ * Rails 4.0 or higher
28
+
29
+
24
30
  ## Usage
25
31
 
26
32
  This gem works with ActiveRecord, and by convention looks for a `title` method and a `permalink` string field on the model:
@@ -68,6 +74,8 @@ $ bundle exec rspec
68
74
 
69
75
  ## Changelog
70
76
 
77
+ * 1.0.0 -- Internal refactor. Require Rails 4.0 or above and Ruby 2.0 or above. Full release, only took 6 years!
78
+
71
79
  * 0.6.0 -- Switch default replacement character to a dash, but allow the `underscore: true` property to go back to the old format
72
80
 
73
81
  * 0.5.0 -- Fix bugs in `max_length` property which would sometimes allow the permalink to be longer than the value
@@ -1,69 +1,47 @@
1
- # ActsAsPermalink
2
- module Acts #:nodoc:
3
- module Permalink #:nodoc:
1
+ require "string"
2
+ require "config"
4
3
 
5
- def self.included(base)
6
- base.extend ClassMethods
7
- end
4
+ module Acts
5
+ module Permalink
6
+ extend ActiveSupport::Concern
8
7
 
9
- module ClassMethods
8
+ class_methods do
10
9
  def acts_as_permalink(options={})
11
- # Read and scrub option for the column which will save the permalink
12
- self.base_class.instance_variable_set('@permalink_column_name', options[:to].try(:to_sym) || :permalink)
13
-
14
- # Read and scrub the option for the column or function which will generate the permalink
15
- self.base_class.instance_variable_set('@permalink_source', (options[:from].try(:to_sym) || :title))
16
-
17
- # Set the underscore character
18
- self.base_class.instance_variable_set('@permalink_underscore', options[:underscore])
10
+ cattr_accessor :acts_as_permalink_config
11
+ self.acts_as_permalink_config = Acts::Permalink::Config.new(options)
19
12
 
20
- # Read and validate the maximum length of the permalink
21
- max_length = options[:max_length].to_i rescue 0
22
- max_length = 60 unless max_length && max_length > 0
23
- self.base_class.instance_variable_set('@permalink_length', max_length)
24
-
25
- if Rails.version >= "3"
26
- before_validation :update_permalink, on: :create
27
- else
28
- before_validation_on_create :update_permalink
29
- end
13
+ before_validation :update_permalink, on: :create
14
+ validates_uniqueness_of self.acts_as_permalink_config.to
15
+ attr_readonly self.acts_as_permalink_config.to
16
+ end
17
+ end
30
18
 
31
- validates_uniqueness_of @permalink_column_name
32
- attr_readonly @permalink_column_name
19
+ included do
20
+ def to_param
21
+ self.public_send(self.class.base_class.acts_as_permalink_config.to)
22
+ end
33
23
 
34
- include Acts::Permalink::InstanceMethods
35
- extend Acts::Permalink::SingletonMethods
24
+ def update_permalink
25
+ self.public_send("#{ self.class.base_class.acts_as_permalink_config.to }=", build_permalink)
26
+ true
36
27
  end
37
28
 
38
- # Returns the unique permalink string for the passed in object.
39
- def generate_permalink_for(obj)
40
- column_name = obj.class.base_class.instance_variable_get('@permalink_column_name')
41
- text = obj.send(obj.class.base_class.instance_variable_get('@permalink_source'))
42
- max_length = obj.class.base_class.instance_variable_get('@permalink_length')
43
- separator = obj.class.base_class.instance_variable_get('@permalink_underscore') ? "_" : "-"
29
+ def build_permalink
30
+ config = self.class.base_class.acts_as_permalink_config
44
31
 
45
- # If it is blank then generate a random link
46
- if text.blank?
47
- text = obj.class.base_class.to_s.downcase + rand(10000).to_s
48
-
49
- # If it is not blank, scrub
50
- else
51
- text = text.downcase.strip # make the string lowercase and scrub white space on either side
52
- text = text.gsub(/[^a-z0-9\w]/, separator) # make any character that is not nupermic or alphabetic into a special character
53
- text = text.squeeze(separator) # removes any consecutive duplicates of the special character
54
- text = text[0...max_length] # trim to length
55
- text = text.sub(Regexp.new("^#{ separator }+"), "") # remove leading special characters
56
- text = text.sub(Regexp.new("#{ separator }+$"), "") # remove trailing special characters
57
- end
32
+ text = self.public_send(config.from)
33
+ text = [self.class.base_class.to_s, rand(10000)].join(config.separator) if text.blank?
34
+ text = text.to_permalink(separator: config.separator, max_length: config.max_length)
58
35
 
59
36
  # Attempt to find the object by the permalink, and if so there is a collision and we need to de-collision it
60
- if obj.class.base_class.where(column_name => text).first
37
+ if self.class.base_class.where(config.to => text).first
61
38
  candidate_text = nil
62
39
 
40
+ # This will fail if you have a million records with the same name
63
41
  (1..999999).each do |num|
64
- suffix = "#{ separator }#{ num }"
65
- candidate_text = [text[0...(max_length - suffix.length)], suffix].join("")
66
- break unless obj.class.base_class.where(column_name => candidate_text).first
42
+ suffix = "#{ config.separator }#{ num }"
43
+ candidate_text = [text[0...(config.max_length - suffix.length)], suffix].join("")
44
+ break unless self.class.base_class.where(config.to => candidate_text).first
67
45
  end
68
46
 
69
47
  text = candidate_text
@@ -73,22 +51,6 @@ module Acts #:nodoc:
73
51
  end
74
52
  end
75
53
 
76
- module SingletonMethods
77
- end
78
-
79
- module InstanceMethods
80
-
81
- # Override this method so that find searches by permalink and not by id
82
- def to_param
83
- self.send(self.class.base_class.instance_variable_get('@permalink_column_name'))
84
- end
85
-
86
- # Generate the permalink and assign it directly via callback
87
- def update_permalink
88
- self.send("#{ self.class.base_class.instance_variable_get('@permalink_column_name') }=", self.class.base_class.generate_permalink_for(self))
89
- true
90
- end
91
- end
92
54
  end
93
55
  end
94
56
 
@@ -1,5 +1,5 @@
1
1
  module Acts
2
2
  module Permalink
3
- VERSION = "0.6.0"
3
+ VERSION = "1.0.0"
4
4
  end
5
5
  end
data/lib/config.rb ADDED
@@ -0,0 +1,18 @@
1
+ module Acts
2
+ module Permalink
3
+ class Config
4
+ attr_reader :to, :from, :separator, :max_length
5
+
6
+ def initialize(options={})
7
+ @config = options.with_indifferent_access
8
+
9
+ @to = @config[:to].try(:to_sym) || :permalink
10
+ @from = @config[:from].try(:to_sym) || :title
11
+ @separator = @config[:underscore] ? "_" : "-"
12
+
13
+ @max_length = @config[:max_length].to_i rescue 0
14
+ @max_length = 60 unless @max_length > 0
15
+ end
16
+ end
17
+ end
18
+ end
data/lib/string.rb ADDED
@@ -0,0 +1,14 @@
1
+ class String
2
+ def to_permalink(max_length: nil, separator: "-")
3
+ text = self.dup
4
+
5
+ text = text.downcase.strip # make the string lowercase and scrub white space on either side
6
+ text = text.gsub(/[^a-z0-9]/, separator) # make any character that is not nupermic or alphabetic into a special character
7
+ text = text.squeeze(separator) # removes any consecutive duplicates of the special character
8
+ text = text.sub(Regexp.new("^#{ separator }+"), "") # remove leading special characters
9
+ text = text.sub(Regexp.new("#{ separator }+$"), "") # remove trailing special characters
10
+ text = text[0...max_length] if max_length # trim to length
11
+
12
+ text
13
+ end
14
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: acts_as_permalink
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin McPhillips
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-26 00:00:00.000000000 Z
11
+ date: 2015-10-27 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: '3.0'
19
+ version: '4.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: '3.0'
26
+ version: '4.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rspec
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -75,10 +75,12 @@ extensions: []
75
75
  extra_rdoc_files: []
76
76
  files:
77
77
  - MIT-LICENSE
78
- - README.markdown
78
+ - README.md
79
79
  - Rakefile
80
80
  - lib/acts_as_permalink.rb
81
81
  - lib/acts_as_permalink/version.rb
82
+ - lib/config.rb
83
+ - lib/string.rb
82
84
  homepage: http://github.com/kmcphillips/acts_as_permalink
83
85
  licenses: []
84
86
  metadata: {}