File: object_utils.rb

package info (click to toggle)
ruby-friendly-id 5.5.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 432 kB
  • sloc: ruby: 3,143; makefile: 3
file content (76 lines) | stat: -rw-r--r-- 2,406 bytes parent folder | download
1
2
3
4
5
6
7
8
9
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
module FriendlyId
  # Instances of these classes will never be considered a friendly id.
  # @see FriendlyId::ObjectUtils#friendly_id
  UNFRIENDLY_CLASSES = [
    Array,
    FalseClass,
    Hash,
    NilClass,
    Numeric,
    Symbol,
    TrueClass
  ]

  # Utility methods for determining whether any object is a friendly id.
  #
  # Monkey-patching Object is a somewhat extreme measure not to be taken lightly
  # by libraries, but in this case I decided to do it because to me, it feels
  # cleaner than adding a module method to {FriendlyId}. I've given the methods
  # names that unambigously refer to the library of their origin, which should
  # be sufficient to avoid conflicts with other libraries.
  module ObjectUtils
    # True if the id is definitely friendly, false if definitely unfriendly,
    # else nil.
    #
    # An object is considired "definitely unfriendly" if its class is or
    # inherits from ActiveRecord::Base, Array, Hash, NilClass, Numeric, or
    # Symbol.
    #
    # An object is considered "definitely friendly" if it responds to +to_i+,
    # and its value when cast to an integer and then back to a string is
    # different from its value when merely cast to a string:
    #
    #     123.friendly_id?                  #=> false
    #     :id.friendly_id?                  #=> false
    #     {:name => 'joe'}.friendly_id?     #=> false
    #     ['name = ?', 'joe'].friendly_id?  #=> false
    #     nil.friendly_id?                  #=> false
    #     "123".friendly_id?                #=> nil
    #     "abc123".friendly_id?             #=> true
    def friendly_id?
      true if respond_to?(:to_i) && to_i.to_s != to_s
    end

    # True if the id is definitely unfriendly, false if definitely friendly,
    # else nil.
    def unfriendly_id?
      val = friendly_id?
      !val unless val.nil?
    end
  end

  module UnfriendlyUtils
    def friendly_id?
      false
    end

    def unfriendly_id?
      true
    end
  end

  def self.mark_as_unfriendly(klass)
    klass.send(:include, FriendlyId::UnfriendlyUtils)
  end
end

Object.send :include, FriendlyId::ObjectUtils

# Considered unfriendly if object is an instance of an unfriendly class or
# one of its descendants.

FriendlyId::UNFRIENDLY_CLASSES.each { |klass| FriendlyId.mark_as_unfriendly(klass) }

ActiveSupport.on_load(:active_record) do
  FriendlyId.mark_as_unfriendly(ActiveRecord::Base)
end