File: candidates.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 (71 lines) | stat: -rw-r--r-- 1,673 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
require "securerandom"

module FriendlyId
  # This class provides the slug candidate functionality.
  # @see FriendlyId::Slugged
  class Candidates
    include Enumerable

    def initialize(object, *array)
      @object = object
      @raw_candidates = to_candidate_array(object, array.flatten(1))
    end

    def each(*args, &block)
      return candidates unless block
      candidates.each { |candidate| yield candidate }
    end

    private

    def candidates
      @candidates ||= begin
        candidates = normalize(@raw_candidates)
        filter(candidates)
      end
    end

    def normalize(candidates)
      candidates.map do |candidate|
        @object.normalize_friendly_id(candidate.map(&:call).join(" "))
      end.select { |x| wanted?(x) }
    end

    def filter(candidates)
      unless candidates.all? { |x| reserved?(x) }
        candidates.reject! { |x| reserved?(x) }
      end
      candidates
    end

    def to_candidate_array(object, array)
      array.map do |candidate|
        case candidate
        when String
          [-> { candidate }]
        when Array
          to_candidate_array(object, candidate).flatten
        when Symbol
          [object.method(candidate)]
        else
          if candidate.respond_to?(:call)
            [candidate]
          else
            [-> { candidate.to_s }]
          end
        end
      end
    end

    def wanted?(slug)
      slug.present?
    end

    def reserved?(slug)
      config = @object.friendly_id_config
      return false unless config.uses? ::FriendlyId::Reserved
      return false unless config.reserved_words
      config.reserved_words.include?(slug)
    end
  end
end