friendly_id 5.4.1 → 5.5.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.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.github/dependabot.yml +6 -0
  4. data/.github/workflows/test.yml +38 -36
  5. data/.yardopts +2 -0
  6. data/Changelog.md +15 -0
  7. data/Gemfile +9 -13
  8. data/README.md +21 -0
  9. data/Rakefile +24 -27
  10. data/bench.rb +30 -27
  11. data/certs/parndt.pem +25 -23
  12. data/friendly_id.gemspec +26 -29
  13. data/gemfiles/Gemfile.rails-5.2.rb +11 -16
  14. data/gemfiles/Gemfile.rails-6.0.rb +11 -16
  15. data/gemfiles/Gemfile.rails-6.1.rb +22 -0
  16. data/gemfiles/Gemfile.rails-7.0.rb +22 -0
  17. data/guide.rb +13 -6
  18. data/lib/friendly_id/base.rb +59 -60
  19. data/lib/friendly_id/candidates.rb +9 -11
  20. data/lib/friendly_id/configuration.rb +6 -7
  21. data/lib/friendly_id/finder_methods.rb +63 -15
  22. data/lib/friendly_id/finders.rb +66 -66
  23. data/lib/friendly_id/history.rb +62 -63
  24. data/lib/friendly_id/initializer.rb +4 -4
  25. data/lib/friendly_id/migration.rb +6 -6
  26. data/lib/friendly_id/object_utils.rb +2 -2
  27. data/lib/friendly_id/reserved.rb +30 -32
  28. data/lib/friendly_id/scoped.rb +99 -102
  29. data/lib/friendly_id/sequentially_slugged/calculator.rb +69 -0
  30. data/lib/friendly_id/sequentially_slugged.rb +17 -64
  31. data/lib/friendly_id/simple_i18n.rb +78 -69
  32. data/lib/friendly_id/slug.rb +1 -2
  33. data/lib/friendly_id/slug_generator.rb +1 -3
  34. data/lib/friendly_id/slugged.rb +237 -238
  35. data/lib/friendly_id/version.rb +1 -1
  36. data/lib/friendly_id.rb +47 -49
  37. data/lib/generators/friendly_id_generator.rb +9 -9
  38. data/test/base_test.rb +10 -13
  39. data/test/benchmarks/finders.rb +28 -26
  40. data/test/benchmarks/object_utils.rb +13 -13
  41. data/test/candidates_test.rb +17 -18
  42. data/test/configuration_test.rb +7 -11
  43. data/test/core_test.rb +1 -2
  44. data/test/databases.yml +4 -3
  45. data/test/finders_test.rb +36 -13
  46. data/test/generator_test.rb +16 -26
  47. data/test/helper.rb +31 -24
  48. data/test/history_test.rb +70 -74
  49. data/test/numeric_slug_test.rb +4 -4
  50. data/test/object_utils_test.rb +0 -2
  51. data/test/reserved_test.rb +9 -11
  52. data/test/schema.rb +5 -4
  53. data/test/scoped_test.rb +18 -20
  54. data/test/sequentially_slugged_test.rb +65 -50
  55. data/test/shared.rb +15 -16
  56. data/test/simple_i18n_test.rb +22 -12
  57. data/test/slugged_test.rb +125 -113
  58. data/test/sti_test.rb +19 -21
  59. data.tar.gz.sig +0 -0
  60. metadata +37 -32
  61. metadata.gz.sig +0 -0
@@ -0,0 +1,22 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec path: "../"
4
+
5
+ gem "activerecord", "~> 6.1.4"
6
+ gem "railties", "~> 6.1.4"
7
+
8
+ # Database Configuration
9
+ group :development, :test do
10
+ platforms :jruby do
11
+ gem "activerecord-jdbcmysql-adapter", "~> 61.0"
12
+ gem "activerecord-jdbcpostgresql-adapter", "~> 61.0"
13
+ gem "kramdown"
14
+ end
15
+
16
+ platforms :ruby, :rbx do
17
+ gem "sqlite3"
18
+ gem "mysql2"
19
+ gem "pg"
20
+ gem "redcarpet"
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec path: "../"
4
+
5
+ gem "activerecord", "~> 7.0.0"
6
+ gem "railties", "~> 7.0.0"
7
+
8
+ # Database Configuration
9
+ group :development, :test do
10
+ platforms :jruby do
11
+ gem "activerecord-jdbcmysql-adapter", "~> 61.0"
12
+ gem "activerecord-jdbcpostgresql-adapter", "~> 61.0"
13
+ gem "kramdown"
14
+ end
15
+
16
+ platforms :ruby, :rbx do
17
+ gem "sqlite3"
18
+ gem "mysql2"
19
+ gem "pg"
20
+ gem "redcarpet"
21
+ end
22
+ end
data/guide.rb CHANGED
@@ -3,14 +3,21 @@
3
3
  # This script generates the Guide.md file included in the Yard docs.
4
4
 
5
5
  def comments_from path
6
- path = File.expand_path("../lib/friendly_id/#{path}", __FILE__)
7
- match = File.read(path).match(/\n=begin(.*)\n=end/m)[1].to_s
8
- match.split("\n").reject {|x| x =~ /^@/}.join("\n").strip
6
+ path = File.expand_path("../lib/friendly_id/#{path}", __FILE__)
7
+ matches = File.read(path).match(/\n\s*# @guide begin\n(.*)\s*# @guide end/m)
8
+
9
+ return if matches.nil?
10
+
11
+ match = matches[1].to_s
12
+ match.split("\n")
13
+ .map { |x| x.sub(/^\s*#\s?/, "") } # Strip off the comment, leading whitespace, and the space after the comment
14
+ .reject { |x| x =~ /^@/ } # Ignore yarddoc tags for the guide
15
+ .join("\n").strip
9
16
  end
10
17
 
11
- File.open(File.expand_path('../Guide.md', __FILE__), 'w:utf-8') do |guide|
12
- ['../friendly_id.rb', 'base.rb', 'finders.rb', 'slugged.rb', 'history.rb',
13
- 'scoped.rb', 'simple_i18n.rb', 'reserved.rb'].each do |file|
18
+ File.open(File.expand_path("../Guide.md", __FILE__), "w:utf-8") do |guide|
19
+ ["../friendly_id.rb", "base.rb", "finders.rb", "slugged.rb", "history.rb",
20
+ "scoped.rb", "simple_i18n.rb", "reserved.rb"].each do |file|
14
21
  guide.write comments_from file
15
22
  guide.write "\n"
16
23
  end
@@ -1,62 +1,61 @@
1
1
  module FriendlyId
2
- =begin
3
-
4
- ## Setting Up FriendlyId in Your Model
5
-
6
- To use FriendlyId in your ActiveRecord models, you must first either extend or
7
- include the FriendlyId module (it makes no difference), then invoke the
8
- {FriendlyId::Base#friendly_id friendly_id} method to configure your desired
9
- options:
10
-
11
- class Foo < ActiveRecord::Base
12
- include FriendlyId
13
- friendly_id :bar, :use => [:slugged, :simple_i18n]
14
- end
15
-
16
- The most important option is `:use`, which you use to tell FriendlyId which
17
- addons it should use. See the documentation for {FriendlyId::Base#friendly_id} for a list of all
18
- available addons, or skim through the rest of the docs to get a high-level
19
- overview.
20
-
21
- *A note about single table inheritance (STI): you must extend FriendlyId in
22
- all classes that participate in STI, both your parent classes and their
23
- children.*
24
-
25
- ### The Default Setup: Simple Models
26
-
27
- The simplest way to use FriendlyId is with a model that has a uniquely indexed
28
- column with no spaces or special characters, and that is seldom or never
29
- updated. The most common example of this is a user name:
30
-
31
- class User < ActiveRecord::Base
32
- extend FriendlyId
33
- friendly_id :login
34
- validates_format_of :login, :with => /\A[a-z0-9]+\z/i
35
- end
36
-
37
- @user = User.friendly.find "joe" # the old User.find(1) still works, too
38
- @user.to_param # returns "joe"
39
- redirect_to @user # the URL will be /users/joe
40
-
41
- In this case, FriendlyId assumes you want to use the column as-is; it will never
42
- modify the value of the column, and your application should ensure that the
43
- value is unique and admissible in a URL:
44
-
45
- class City < ActiveRecord::Base
46
- extend FriendlyId
47
- friendly_id :name
48
- end
49
-
50
- @city.friendly.find "Viña del Mar"
51
- redirect_to @city # the URL will be /cities/Viña%20del%20Mar
52
-
53
- Writing the code to process an arbitrary string into a good identifier for use
54
- in a URL can be repetitive and surprisingly tricky, so for this reason it's
55
- often better and easier to use {FriendlyId::Slugged slugs}.
56
-
57
- =end
2
+ # @guide begin
3
+ #
4
+ # ## Setting Up FriendlyId in Your Model
5
+ #
6
+ # To use FriendlyId in your ActiveRecord models, you must first either extend or
7
+ # include the FriendlyId module (it makes no difference), then invoke the
8
+ # {FriendlyId::Base#friendly_id friendly_id} method to configure your desired
9
+ # options:
10
+ #
11
+ # class Foo < ActiveRecord::Base
12
+ # include FriendlyId
13
+ # friendly_id :bar, :use => [:slugged, :simple_i18n]
14
+ # end
15
+ #
16
+ # The most important option is `:use`, which you use to tell FriendlyId which
17
+ # addons it should use. See the documentation for {FriendlyId::Base#friendly_id} for a list of all
18
+ # available addons, or skim through the rest of the docs to get a high-level
19
+ # overview.
20
+ #
21
+ # *A note about single table inheritance (STI): you must extend FriendlyId in
22
+ # all classes that participate in STI, both your parent classes and their
23
+ # children.*
24
+ #
25
+ # ### The Default Setup: Simple Models
26
+ #
27
+ # The simplest way to use FriendlyId is with a model that has a uniquely indexed
28
+ # column with no spaces or special characters, and that is seldom or never
29
+ # updated. The most common example of this is a user name:
30
+ #
31
+ # class User < ActiveRecord::Base
32
+ # extend FriendlyId
33
+ # friendly_id :login
34
+ # validates_format_of :login, :with => /\A[a-z0-9]+\z/i
35
+ # end
36
+ #
37
+ # @user = User.friendly.find "joe" # the old User.find(1) still works, too
38
+ # @user.to_param # returns "joe"
39
+ # redirect_to @user # the URL will be /users/joe
40
+ #
41
+ # In this case, FriendlyId assumes you want to use the column as-is; it will never
42
+ # modify the value of the column, and your application should ensure that the
43
+ # value is unique and admissible in a URL:
44
+ #
45
+ # class City < ActiveRecord::Base
46
+ # extend FriendlyId
47
+ # friendly_id :name
48
+ # end
49
+ #
50
+ # @city.friendly.find "Viña del Mar"
51
+ # redirect_to @city # the URL will be /cities/Viña%20del%20Mar
52
+ #
53
+ # Writing the code to process an arbitrary string into a good identifier for use
54
+ # in a URL can be repetitive and surprisingly tricky, so for this reason it's
55
+ # often better and easier to use {FriendlyId::Slugged slugs}.
56
+ #
57
+ # @guide end
58
58
  module Base
59
-
60
59
  # Configure FriendlyId's behavior in a model.
61
60
  #
62
61
  # class Post < ActiveRecord::Base
@@ -205,10 +204,10 @@ often better and easier to use {FriendlyId::Slugged slugs}.
205
204
  #
206
205
  # @yieldparam config The model class's {FriendlyId::Configuration friendly_id_config}.
207
206
  def friendly_id(base = nil, options = {}, &block)
208
- yield friendly_id_config if block_given?
207
+ yield friendly_id_config if block
209
208
  friendly_id_config.dependent = options.delete :dependent
210
209
  friendly_id_config.use options.delete :use
211
- friendly_id_config.send :set, base ? options.merge(:base => base) : options
210
+ friendly_id_config.send :set, base ? options.merge(base: base) : options
212
211
  include Model
213
212
  end
214
213
 
@@ -270,7 +269,7 @@ often better and easier to use {FriendlyId::Slugged slugs}.
270
269
 
271
270
  # Clears slug on duplicate records when calling `dup`.
272
271
  def dup
273
- super.tap { |duplicate| duplicate.slug = nil if duplicate.respond_to?('slug=') }
272
+ super.tap { |duplicate| duplicate.slug = nil if duplicate.respond_to?("slug=") }
274
273
  end
275
274
  end
276
275
  end
@@ -1,11 +1,9 @@
1
- require 'securerandom'
1
+ require "securerandom"
2
2
 
3
3
  module FriendlyId
4
-
5
4
  # This class provides the slug candidate functionality.
6
5
  # @see FriendlyId::Slugged
7
6
  class Candidates
8
-
9
7
  include Enumerable
10
8
 
11
9
  def initialize(object, *array)
@@ -14,8 +12,8 @@ module FriendlyId
14
12
  end
15
13
 
16
14
  def each(*args, &block)
17
- return candidates unless block_given?
18
- candidates.each{ |candidate| yield candidate }
15
+ return candidates unless block
16
+ candidates.each { |candidate| yield candidate }
19
17
  end
20
18
 
21
19
  private
@@ -29,13 +27,13 @@ module FriendlyId
29
27
 
30
28
  def normalize(candidates)
31
29
  candidates.map do |candidate|
32
- @object.normalize_friendly_id(candidate.map(&:call).join(' '))
33
- end.select {|x| wanted?(x)}
30
+ @object.normalize_friendly_id(candidate.map(&:call).join(" "))
31
+ end.select { |x| wanted?(x) }
34
32
  end
35
33
 
36
34
  def filter(candidates)
37
- unless candidates.all? {|x| reserved?(x)}
38
- candidates.reject! {|x| reserved?(x)}
35
+ unless candidates.all? { |x| reserved?(x) }
36
+ candidates.reject! { |x| reserved?(x) }
39
37
  end
40
38
  candidates
41
39
  end
@@ -44,7 +42,7 @@ module FriendlyId
44
42
  array.map do |candidate|
45
43
  case candidate
46
44
  when String
47
- [->{candidate}]
45
+ [-> { candidate }]
48
46
  when Array
49
47
  to_candidate_array(object, candidate).flatten
50
48
  when Symbol
@@ -53,7 +51,7 @@ module FriendlyId
53
51
  if candidate.respond_to?(:call)
54
52
  [candidate]
55
53
  else
56
- [->{candidate.to_s}]
54
+ [-> { candidate.to_s }]
57
55
  end
58
56
  end
59
57
  end
@@ -2,7 +2,6 @@ module FriendlyId
2
2
  # The configuration parameters passed to {Base#friendly_id} will be stored in
3
3
  # this object.
4
4
  class Configuration
5
-
6
5
  attr_writer :base
7
6
 
8
7
  # The default configuration options.
@@ -25,10 +24,10 @@ module FriendlyId
25
24
  attr_accessor :routes
26
25
 
27
26
  def initialize(model_class, values = nil)
28
- @base = nil
29
- @model_class = model_class
30
- @defaults = {}
31
- @modules = []
27
+ @base = nil
28
+ @model_class = model_class
29
+ @defaults = {}
30
+ @modules = []
32
31
  @finder_methods = FriendlyId::FinderMethods
33
32
  self.routes = :friendly
34
33
  set values
@@ -102,11 +101,11 @@ module FriendlyId
102
101
  private
103
102
 
104
103
  def get_module(object)
105
- Module === object ? object : FriendlyId.const_get(object.to_s.titleize.camelize.gsub(/\s+/, ''))
104
+ Module === object ? object : FriendlyId.const_get(object.to_s.titleize.camelize.gsub(/\s+/, ""))
106
105
  end
107
106
 
108
107
  def set(values)
109
- values and values.each {|name, value| self.send "#{name}=", value}
108
+ values&.each { |name, value| send "#{name}=", value }
110
109
  end
111
110
  end
112
111
  end
@@ -1,7 +1,5 @@
1
1
  module FriendlyId
2
-
3
2
  module FinderMethods
4
-
5
3
  # Finds a record using the given id.
6
4
  #
7
5
  # If the id is "unfriendly", it will call the original find method.
@@ -9,19 +7,33 @@ module FriendlyId
9
7
  # id matching '123' and then fall back to looking for a record with the
10
8
  # numeric id '123'.
11
9
  #
10
+ # @param [Boolean] allow_nil (default: false)
11
+ # Use allow_nil: true if you'd like the finder to return nil instead of
12
+ # raising ActivRecord::RecordNotFound
13
+ #
14
+ # ### Example
15
+ #
16
+ # MyModel.friendly.find("bad-slug")
17
+ # #=> raise ActiveRecord::RecordNotFound
18
+ #
19
+ # MyModel.friendly.find("bad-slug", allow_nil: true)
20
+ # #=> nil
21
+ #
12
22
  # Since FriendlyId 5.0, if the id is a nonnumeric string like '123-foo' it
13
23
  # will *only* search by friendly id and not fall back to the regular find
14
24
  # method.
15
25
  #
16
26
  # If you want to search only by the friendly id, use {#find_by_friendly_id}.
17
27
  # @raise ActiveRecord::RecordNotFound
18
- def find(*args)
28
+ def find(*args, allow_nil: false)
19
29
  id = args.first
20
- return super if args.count != 1 || id.unfriendly_id?
21
- first_by_friendly_id(id).tap {|result| return result unless result.nil?}
22
- return super if potential_primary_key?(id)
23
- raise_not_found_exception id
24
-
30
+ return super(*args) if args.count != 1 || id.unfriendly_id?
31
+ first_by_friendly_id(id).tap { |result| return result unless result.nil? }
32
+ return super(*args) if potential_primary_key?(id)
33
+
34
+ raise_not_found_exception(id) unless allow_nil
35
+ rescue ActiveRecord::RecordNotFound => exception
36
+ raise exception unless allow_nil
25
37
  end
26
38
 
27
39
  # Returns true if a record with the given id exists.
@@ -35,11 +47,11 @@ module FriendlyId
35
47
  # `find`.
36
48
  # @raise ActiveRecord::RecordNotFound
37
49
  def find_by_friendly_id(id)
38
- first_by_friendly_id(id) or raise raise_not_found_exception(id)
50
+ first_by_friendly_id(id) or raise_not_found_exception(id)
39
51
  end
40
52
 
41
53
  def exists_by_friendly_id?(id)
42
- where(friendly_id_config.query_field => id).exists?
54
+ where(friendly_id_config.query_field => parse_friendly_id(id)).exists?
43
55
  end
44
56
 
45
57
  private
@@ -50,7 +62,11 @@ module FriendlyId
50
62
  key_type = key_type.type if key_type.respond_to?(:type)
51
63
  case key_type
52
64
  when :integer
53
- Integer(id, 10) rescue false
65
+ begin
66
+ Integer(id, 10)
67
+ rescue
68
+ false
69
+ end
54
70
  when :uuid
55
71
  id.match(/\A[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\z/)
56
72
  else
@@ -59,17 +75,49 @@ module FriendlyId
59
75
  end
60
76
 
61
77
  def first_by_friendly_id(id)
62
- find_by(friendly_id_config.query_field => id.downcase)
78
+ find_by(friendly_id_config.query_field => parse_friendly_id(id))
79
+ end
80
+
81
+ # Parse the given value to make it suitable for use as a slug according to
82
+ # your application's rules.
83
+ #
84
+ # This method is not intended to be invoked directly; FriendlyId uses it
85
+ # internally to process a slug into string to use as a finder.
86
+ #
87
+ # However, if FriendlyId's default slug parsing doesn't suit your needs,
88
+ # you can override this method in your model class to control exactly how
89
+ # slugs are generated.
90
+ #
91
+ # ### Example
92
+ #
93
+ # class Person < ActiveRecord::Base
94
+ # extend FriendlyId
95
+ # friendly_id :name_and_location
96
+ #
97
+ # def name_and_location
98
+ # "#{name} from #{location}"
99
+ # end
100
+ #
101
+ # # Use default slug, but lower case
102
+ # # If `id` is "Jane-Doe" or "JANE-DOE", this finds data by "jane-doe"
103
+ # def parse_friendly_id(slug)
104
+ # super.downcase
105
+ # end
106
+ # end
107
+ #
108
+ # @param [#to_s] value The slug to be parsed.
109
+ # @return The parsed slug, which is not modified by default.
110
+ def parse_friendly_id(value)
111
+ value
63
112
  end
64
113
 
65
114
  def raise_not_found_exception(id)
66
115
  message = "can't find record with friendly id: #{id.inspect}"
67
- if ActiveRecord.version < Gem::Version.create('5.0') then
116
+ if ActiveRecord.version < Gem::Version.create("5.0")
68
117
  raise ActiveRecord::RecordNotFound.new(message)
69
- else
118
+ else
70
119
  raise ActiveRecord::RecordNotFound.new(message, name, friendly_id_config.query_field, id)
71
120
  end
72
121
  end
73
-
74
122
  end
75
123
  end
@@ -1,73 +1,73 @@
1
1
  module FriendlyId
2
- =begin
3
- ## Performing Finds with FriendlyId
4
-
5
- FriendlyId offers enhanced finders which will search for your record by
6
- friendly id, and fall back to the numeric id if necessary. This makes it easy
7
- to add FriendlyId to an existing application with minimal code modification.
8
-
9
- By default, these methods are available only on the `friendly` scope:
10
-
11
- Restaurant.friendly.find('plaza-diner') #=> works
12
- Restaurant.friendly.find(23) #=> also works
13
- Restaurant.find(23) #=> still works
14
- Restaurant.find('plaza-diner') #=> will not work
15
-
16
- ### Restoring FriendlyId 4.0-style finders
17
-
18
- Prior to version 5.0, FriendlyId overrode the default finder methods to perform
19
- friendly finds all the time. This required modifying parts of Rails that did
20
- not have a public API, which was harder to maintain and at times caused
21
- compatiblity problems. In 5.0 we decided to change the library's defaults and add
22
- the friendly finder methods only to the `friendly` scope in order to boost
23
- compatiblity. However, you can still opt-in to original functionality very
24
- easily by using the `:finders` addon:
25
-
26
- class Restaurant < ActiveRecord::Base
27
- extend FriendlyId
28
-
29
- scope :active, -> {where(:active => true)}
30
-
31
- friendly_id :name, :use => [:slugged, :finders]
32
- end
33
-
34
- Restaurant.friendly.find('plaza-diner') #=> works
35
- Restaurant.find('plaza-diner') #=> now also works
36
- Restaurant.active.find('plaza-diner') #=> now also works
37
-
38
- ### Updating your application to use FriendlyId's finders
39
-
40
- Unless you've chosen to use the `:finders` addon, be sure to modify the finders
41
- in your controllers to use the `friendly` scope. For example:
42
-
43
- # before
44
- def set_restaurant
45
- @restaurant = Restaurant.find(params[:id])
46
- end
47
-
48
- # after
49
- def set_restaurant
50
- @restaurant = Restaurant.friendly.find(params[:id])
51
- end
52
-
53
- #### Active Admin
54
-
55
- Unless you use the `:finders` addon, you should modify your admin controllers
56
- for models that use FriendlyId with something similar to the following:
57
-
58
- controller do
59
- def find_resource
60
- scoped_collection.friendly.find(params[:id])
61
- end
62
- end
63
-
64
- =end
2
+ # @guide begin
3
+ #
4
+ # ## Performing Finds with FriendlyId
5
+ #
6
+ # FriendlyId offers enhanced finders which will search for your record by
7
+ # friendly id, and fall back to the numeric id if necessary. This makes it easy
8
+ # to add FriendlyId to an existing application with minimal code modification.
9
+ #
10
+ # By default, these methods are available only on the `friendly` scope:
11
+ #
12
+ # Restaurant.friendly.find('plaza-diner') #=> works
13
+ # Restaurant.friendly.find(23) #=> also works
14
+ # Restaurant.find(23) #=> still works
15
+ # Restaurant.find('plaza-diner') #=> will not work
16
+ #
17
+ # ### Restoring FriendlyId 4.0-style finders
18
+ #
19
+ # Prior to version 5.0, FriendlyId overrode the default finder methods to perform
20
+ # friendly finds all the time. This required modifying parts of Rails that did
21
+ # not have a public API, which was harder to maintain and at times caused
22
+ # compatiblity problems. In 5.0 we decided to change the library's defaults and add
23
+ # the friendly finder methods only to the `friendly` scope in order to boost
24
+ # compatiblity. However, you can still opt-in to original functionality very
25
+ # easily by using the `:finders` addon:
26
+ #
27
+ # class Restaurant < ActiveRecord::Base
28
+ # extend FriendlyId
29
+ #
30
+ # scope :active, -> {where(:active => true)}
31
+ #
32
+ # friendly_id :name, :use => [:slugged, :finders]
33
+ # end
34
+ #
35
+ # Restaurant.friendly.find('plaza-diner') #=> works
36
+ # Restaurant.find('plaza-diner') #=> now also works
37
+ # Restaurant.active.find('plaza-diner') #=> now also works
38
+ #
39
+ # ### Updating your application to use FriendlyId's finders
40
+ #
41
+ # Unless you've chosen to use the `:finders` addon, be sure to modify the finders
42
+ # in your controllers to use the `friendly` scope. For example:
43
+ #
44
+ # # before
45
+ # def set_restaurant
46
+ # @restaurant = Restaurant.find(params[:id])
47
+ # end
48
+ #
49
+ # # after
50
+ # def set_restaurant
51
+ # @restaurant = Restaurant.friendly.find(params[:id])
52
+ # end
53
+ #
54
+ # #### Active Admin
55
+ #
56
+ # Unless you use the `:finders` addon, you should modify your admin controllers
57
+ # for models that use FriendlyId with something similar to the following:
58
+ #
59
+ # controller do
60
+ # def find_resource
61
+ # scoped_collection.friendly.find(params[:id])
62
+ # end
63
+ # end
64
+ #
65
+ # @guide end
65
66
  module Finders
66
-
67
67
  module ClassMethods
68
68
  if (ActiveRecord::VERSION::MAJOR == 4) && (ActiveRecord::VERSION::MINOR == 0)
69
69
  def relation_delegate_class(klass)
70
- relation_class_name = :"#{klass.to_s.gsub('::', '_')}_#{self.to_s.gsub('::', '_')}"
70
+ relation_class_name = :"#{klass.to_s.gsub("::", "_")}_#{to_s.gsub("::", "_")}"
71
71
  klass.const_get(relation_class_name)
72
72
  end
73
73
  end
@@ -82,7 +82,7 @@ for models that use FriendlyId with something similar to the following:
82
82
  end
83
83
 
84
84
  # Support for friendly finds on associations for Rails 4.0.1 and above.
85
- if ::ActiveRecord.const_defined?('AssociationRelation')
85
+ if ::ActiveRecord.const_defined?("AssociationRelation")
86
86
  model_class.extend(ClassMethods)
87
87
  association_relation_delegate_class = model_class.relation_delegate_class(::ActiveRecord::AssociationRelation)
88
88
  association_relation_delegate_class.send(:include, model_class.friendly_id_config.finder_methods)