friendly_id 5.2.0.beta.1 → 5.2.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 +4 -4
- data/.travis.yml +15 -4
- data/CONTRIBUTING.md +1 -1
- data/Changelog.md +6 -2
- data/MIT-LICENSE +1 -1
- data/README.md +2 -2
- data/Rakefile +10 -0
- data/bench.rb +6 -6
- data/friendly_id.gemspec +1 -1
- data/gemfiles/Gemfile.rails-4.0.rb +1 -1
- data/gemfiles/Gemfile.rails-4.1.rb +1 -1
- data/gemfiles/Gemfile.rails-5.0.rb +28 -0
- data/lib/friendly_id.rb +1 -13
- data/lib/friendly_id/base.rb +21 -4
- data/lib/friendly_id/configuration.rb +7 -0
- data/lib/friendly_id/finder_methods.rb +4 -4
- data/lib/friendly_id/finders.rb +2 -5
- data/lib/friendly_id/history.rb +12 -10
- data/lib/friendly_id/migration.rb +2 -2
- data/lib/friendly_id/object_utils.rb +29 -7
- data/lib/friendly_id/sequentially_slugged.rb +3 -5
- data/lib/friendly_id/simple_i18n.rb +3 -3
- data/lib/friendly_id/slugged.rb +1 -0
- data/lib/friendly_id/version.rb +1 -1
- data/test/benchmarks/finders.rb +88 -0
- data/test/benchmarks/object_utils.rb +56 -0
- data/test/history_test.rb +74 -5
- data/test/sequentially_slugged_test.rb +16 -0
- data/test/slugged_test.rb +32 -0
- metadata +9 -7
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 606af0800382602b2f88d11be3a839a3e8c23255
         | 
| 4 | 
            +
              data.tar.gz: a501dd78829d595fe897475bdf4a6c6d98caee9c
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: cb2afe89084b532541152c46056649ec6bfca0a2fe51493706f7f996ee233bae010a248a735fb55451e89b1918b29e60b5471e78c0272f29a5c5c410220eacc8
         | 
| 7 | 
            +
              data.tar.gz: 8a527f735585ce88c1627bc54f206745f69a826d27574f6d306ee4a29dff23421e82225b0b9e9751cdd5a3a9911f3dba755d10d7a9951758052a3bd869b26441
         | 
    
        data/.travis.yml
    CHANGED
    
    | @@ -2,11 +2,11 @@ language: ruby | |
| 2 2 | 
             
            cache: bundler
         | 
| 3 3 |  | 
| 4 4 | 
             
            rvm:
         | 
| 5 | 
            +
              - 2.3.0
         | 
| 5 6 | 
             
              - 2.2.0
         | 
| 6 | 
            -
              - 2.0.0
         | 
| 7 7 | 
             
              - 2.1.0
         | 
| 8 | 
            -
              -  | 
| 9 | 
            -
              -  | 
| 8 | 
            +
              - 2.0.0
         | 
| 9 | 
            +
              - jruby-9.0.4.0
         | 
| 10 10 |  | 
| 11 11 | 
             
            env:
         | 
| 12 12 | 
             
              - DB=postgres
         | 
| @@ -16,15 +16,26 @@ gemfile: | |
| 16 16 | 
             
              - gemfiles/Gemfile.rails-4.0.rb
         | 
| 17 17 | 
             
              - gemfiles/Gemfile.rails-4.1.rb
         | 
| 18 18 | 
             
              - gemfiles/Gemfile.rails-4.2.rb
         | 
| 19 | 
            +
              - gemfiles/Gemfile.rails-5.0.rb
         | 
| 19 20 |  | 
| 20 21 | 
             
            matrix:
         | 
| 21 22 | 
             
              allow_failures:
         | 
| 22 23 | 
             
                - rvm: jruby-19mode
         | 
| 23 24 | 
             
                  gemfile: gemfiles/Gemfile.rails-4.2.rb
         | 
| 24 25 | 
             
                  env: DB=postgres
         | 
| 26 | 
            +
                - rvm: jruby-9.0.4.0
         | 
| 27 | 
            +
                  gemfile: gemfiles/Gemfile.rails-5.0.rb
         | 
| 28 | 
            +
              exclude:
         | 
| 29 | 
            +
                - rvm: 2.0.0
         | 
| 30 | 
            +
                  gemfile: gemfiles/Gemfile.rails-5.0.rb
         | 
| 31 | 
            +
                - rvm: 2.1.0
         | 
| 32 | 
            +
                  gemfile: gemfiles/Gemfile.rails-5.0.rb
         | 
| 33 | 
            +
                - rvm: 2.2.0
         | 
| 34 | 
            +
                  gemfile: gemfiles/Gemfile.rails-5.0.rb
         | 
| 25 35 |  | 
| 26 36 | 
             
            sudo: false
         | 
| 27 37 |  | 
| 28 | 
            -
            before_script: | 
| 38 | 
            +
            before_script:
         | 
| 39 | 
            +
              - bundle exec rake db:create db:up
         | 
| 29 40 |  | 
| 30 41 | 
             
            script: 'COVERALLS=true bundle exec rake test'
         | 
    
        data/CONTRIBUTING.md
    CHANGED
    
    | @@ -3,7 +3,7 @@ | |
| 3 3 | 
             
            Please ask questions on [Stack
         | 
| 4 4 | 
             
            Overflow](http://stackoverflow.com/questions/tagged/friendly-id) using the
         | 
| 5 5 | 
             
            "friendly_id" or "friendly-id" tag. Prior to asking, search and see if your
         | 
| 6 | 
            -
            question has already been  | 
| 6 | 
            +
            question has already been answered.
         | 
| 7 7 |  | 
| 8 8 | 
             
            Please only post issues in Github issues for actual bugs.
         | 
| 9 9 |  | 
    
        data/Changelog.md
    CHANGED
    
    | @@ -1,15 +1,19 @@ | |
| 1 1 | 
             
            # FriendlyId Changelog
         | 
| 2 2 |  | 
| 3 | 
            -
            We would like to think our many  | 
| 3 | 
            +
            We would like to think our many [contributors](https://github.com/norman/friendly_id/graphs/contributors) for
         | 
| 4 4 | 
             
            suggestions, ideas and improvements to FriendlyId.
         | 
| 5 5 |  | 
| 6 | 
            -
            ## 5.2.0 ( | 
| 6 | 
            +
            ## 5.2.0 (2016-12-01)
         | 
| 7 7 |  | 
| 8 8 | 
             
            * Add sequential slug module for FriendlyId 4.x-style sequential slugs. ([#644](https://github.com/norman/friendly_id/pull/644)).
         | 
| 9 9 | 
             
            * Make Candidates#each iterable without block ([#651](https://github.com/norman/friendly_id/pull/651)).
         | 
| 10 10 | 
             
            * Ensure slug history prefers the record that most recently used the slug ([#663](https://github.com/norman/friendly_id/pull/663)).
         | 
| 11 11 | 
             
            * Don't calculate all changes just to check if the param field has changed ([#667](https://github.com/norman/friendly_id/pull/667)).
         | 
| 12 12 | 
             
            * Don't set or change slug when unrelated validation failures block the record from being saved ([#642](https://github.com/norman/friendly_id/issues/642)).
         | 
| 13 | 
            +
            * Fix order dependence bug between history and finders modules ([#718](https://github.com/norman/friendly_id/pull/718))
         | 
| 14 | 
            +
            * Added ability to conditionally turn off :dependent => :destory on FriendlyId::Slugs([#724](https://github.com/norman/friendly_id/pull/724))
         | 
| 15 | 
            +
            * Add support for Rails 5. ([#728](https://github.com/norman/friendly_id/pull/728))
         | 
| 16 | 
            +
            * Allow per-model conditional disabling of friendly path generation using a :routes option to friendly_id ([#735](https://github.com/norman/friendly_id/pull/735))
         | 
| 13 17 |  | 
| 14 18 | 
             
            ## 5.1.0 (2015-01-15)
         | 
| 15 19 |  | 
    
        data/MIT-LICENSE
    CHANGED
    
    | @@ -1,4 +1,4 @@ | |
| 1 | 
            -
            Copyright (c) 2008- | 
| 1 | 
            +
            Copyright (c) 2008-2016 Norman Clarke, Adrian Mugnolo and Emilio Tagua.
         | 
| 2 2 |  | 
| 3 3 | 
             
            Permission is hereby granted, free of charge, to any person obtaining a copy
         | 
| 4 4 | 
             
            of this software and associated documentation files (the "Software"), to deal
         | 
    
        data/README.md
    CHANGED
    
    | @@ -16,7 +16,7 @@ over and over and over again in the issues. | |
| 16 16 |  | 
| 17 17 | 
             
            # FriendlyId
         | 
| 18 18 |  | 
| 19 | 
            -
             | 
| 19 | 
            +
            **For the most complete, user-friendly documentation, see the [FriendlyId Guide](http://norman.github.io/friendly_id/file.Guide.html).**
         | 
| 20 20 |  | 
| 21 21 | 
             
            FriendlyId is the "Swiss Army bulldozer" of slugging and permalink plugins for
         | 
| 22 22 | 
             
            Active Record. It lets you create pretty URLs and work with human-friendly
         | 
| @@ -236,7 +236,7 @@ volunteers](https://github.com/norman/friendly_id/contributors). | |
| 236 236 |  | 
| 237 237 | 
             
            ## License
         | 
| 238 238 |  | 
| 239 | 
            -
            Copyright (c) 2008- | 
| 239 | 
            +
            Copyright (c) 2008-2016 Norman Clarke and contributors, released under the MIT
         | 
| 240 240 | 
             
            license.
         | 
| 241 241 |  | 
| 242 242 | 
             
            Permission is hereby granted, free of charge, to any person obtaining a copy of
         | 
    
        data/Rakefile
    CHANGED
    
    | @@ -36,6 +36,16 @@ task :bench => :load_path do | |
| 36 36 | 
             
              require File.expand_path("../bench", __FILE__)
         | 
| 37 37 | 
             
            end
         | 
| 38 38 |  | 
| 39 | 
            +
            desc "Run benchmarks on finders"
         | 
| 40 | 
            +
            task :bench_finders => :load_path do
         | 
| 41 | 
            +
              require File.expand_path("../test/benchmarks/finders", __FILE__)
         | 
| 42 | 
            +
            end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
            desc "Run benchmarks on ObjectUtils"
         | 
| 45 | 
            +
            task :bench_object_utils => :load_path do
         | 
| 46 | 
            +
              require File.expand_path("../test/benchmarks/object_utils", __FILE__)
         | 
| 47 | 
            +
            end
         | 
| 48 | 
            +
             | 
| 39 49 | 
             
            desc "Generate Guide.md"
         | 
| 40 50 | 
             
            task :guide do
         | 
| 41 51 | 
             
              load File.expand_path('../guide.rb', __FILE__)
         | 
    
        data/bench.rb
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            require File.expand_path("../test/helper", __FILE__)
         | 
| 2 2 | 
             
            require "ffaker"
         | 
| 3 3 |  | 
| 4 | 
            -
            N =  | 
| 4 | 
            +
            N = 10000
         | 
| 5 5 |  | 
| 6 6 | 
             
            def transaction
         | 
| 7 7 | 
             
              ActiveRecord::Base.transaction { yield ; raise ActiveRecord::Rollback }
         | 
| @@ -37,7 +37,7 @@ MANUALS     = [] | |
| 37 37 | 
             
            RESTAURANTS = []
         | 
| 38 38 |  | 
| 39 39 | 
             
            100.times do
         | 
| 40 | 
            -
              name =  | 
| 40 | 
            +
              name = FFaker::Name.name
         | 
| 41 41 | 
             
              BOOKS       << (Book.create! :name => name).id
         | 
| 42 42 | 
             
              JOURNALISTS << (Journalist.create! :name => name).friendly_id
         | 
| 43 43 | 
             
              MANUALS     << (Manual.create! :name => name).friendly_id
         | 
| @@ -64,18 +64,18 @@ Benchmark.bmbm do |x| | |
| 64 64 | 
             
              end
         | 
| 65 65 |  | 
| 66 66 | 
             
              x.report 'insert (without FriendlyId)' do
         | 
| 67 | 
            -
                N.times {transaction {Book.create :name =>  | 
| 67 | 
            +
                N.times {transaction {Book.create :name => FFaker::Name.name}}
         | 
| 68 68 | 
             
              end
         | 
| 69 69 |  | 
| 70 70 | 
             
              x.report 'insert (in-table-slug)' do
         | 
| 71 | 
            -
                N.times {transaction {Journalist.create :name =>  | 
| 71 | 
            +
                N.times {transaction {Journalist.create :name => FFaker::Name.name}}
         | 
| 72 72 | 
             
              end
         | 
| 73 73 |  | 
| 74 74 | 
             
              x.report 'insert (in-table-slug; using finders module)' do
         | 
| 75 | 
            -
                N.times {transaction {Restaurant.create :name =>  | 
| 75 | 
            +
                N.times {transaction {Restaurant.create :name => FFaker::Name.name}}
         | 
| 76 76 | 
             
              end
         | 
| 77 77 |  | 
| 78 78 | 
             
              x.report 'insert (external slug)' do
         | 
| 79 | 
            -
                N.times {transaction {Manual.create :name =>  | 
| 79 | 
            +
                N.times {transaction {Manual.create :name => FFaker::Name.name}}
         | 
| 80 80 | 
             
              end
         | 
| 81 81 | 
             
            end
         | 
    
        data/friendly_id.gemspec
    CHANGED
    
    | @@ -6,7 +6,7 @@ Gem::Specification.new do |s| | |
| 6 6 | 
             
              s.version           = FriendlyId::VERSION
         | 
| 7 7 | 
             
              s.authors           = ["Norman Clarke", "Philip Arndt"]
         | 
| 8 8 | 
             
              s.email             = ["norman@njclarke.com", "p@arndt.io"]
         | 
| 9 | 
            -
              s.homepage          = " | 
| 9 | 
            +
              s.homepage          = "https://github.com/norman/friendly_id"
         | 
| 10 10 | 
             
              s.summary           = "A comprehensive slugging and pretty-URL plugin."
         | 
| 11 11 | 
             
              s.rubyforge_project = "friendly_id"
         | 
| 12 12 | 
             
              s.files             = `git ls-files`.split("\n")
         | 
| @@ -0,0 +1,28 @@ | |
| 1 | 
            +
            source 'https://rubygems.org'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            gemspec path: '../'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            gem 'activerecord', '~> 5.0.0'
         | 
| 6 | 
            +
            gem 'railties', '~> 5.0.0'
         | 
| 7 | 
            +
            gem 'i18n', '~> 0.7.0'
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            # Database Configuration
         | 
| 10 | 
            +
            group :development, :test do
         | 
| 11 | 
            +
              platforms :jruby do
         | 
| 12 | 
            +
                gem 'activerecord-jdbcmysql-adapter', '~> 1.3.14'
         | 
| 13 | 
            +
                gem 'activerecord-jdbcpostgresql-adapter', '~> 1.3.14'
         | 
| 14 | 
            +
                gem 'kramdown'
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              platforms :ruby, :rbx do
         | 
| 18 | 
            +
                gem 'sqlite3'
         | 
| 19 | 
            +
                gem 'mysql2'
         | 
| 20 | 
            +
                gem 'pg'
         | 
| 21 | 
            +
                gem 'redcarpet'
         | 
| 22 | 
            +
              end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
              platforms :rbx do
         | 
| 25 | 
            +
                gem 'rubysl', '~> 2.0'
         | 
| 26 | 
            +
                gem 'rubinius-developer_tools'
         | 
| 27 | 
            +
              end
         | 
| 28 | 
            +
            end
         | 
    
        data/lib/friendly_id.rb
    CHANGED
    
    | @@ -1,4 +1,5 @@ | |
| 1 1 | 
             
            # encoding: utf-8
         | 
| 2 | 
            +
            require 'active_record'
         | 
| 2 3 | 
             
            require "friendly_id/base"
         | 
| 3 4 | 
             
            require "friendly_id/object_utils"
         | 
| 4 5 | 
             
            require "friendly_id/configuration"
         | 
| @@ -51,19 +52,6 @@ module FriendlyId | |
| 51 52 | 
             
              autoload :Finders,             "friendly_id/finders"
         | 
| 52 53 | 
             
              autoload :SequentiallySlugged, "friendly_id/sequentially_slugged"
         | 
| 53 54 |  | 
| 54 | 
            -
              # Instances of these classes will never be considered a friendly id.
         | 
| 55 | 
            -
              # @see FriendlyId::ObjectUtils#friendly_id
         | 
| 56 | 
            -
              UNFRIENDLY_CLASSES = [
         | 
| 57 | 
            -
                ActiveRecord::Base,
         | 
| 58 | 
            -
                Array,
         | 
| 59 | 
            -
                FalseClass,
         | 
| 60 | 
            -
                Hash,
         | 
| 61 | 
            -
                NilClass,
         | 
| 62 | 
            -
                Numeric,
         | 
| 63 | 
            -
                Symbol,
         | 
| 64 | 
            -
                TrueClass
         | 
| 65 | 
            -
              ]
         | 
| 66 | 
            -
             | 
| 67 55 | 
             
              # FriendlyId takes advantage of `extended` to do basic model setup, primarily
         | 
| 68 56 | 
             
              # extending {FriendlyId::Base} to add {FriendlyId::Base#friendly_id
         | 
| 69 57 | 
             
              # friendly_id} as a class method.
         | 
    
        data/lib/friendly_id/base.rb
    CHANGED
    
    | @@ -187,9 +187,22 @@ often better and easier to use {FriendlyId::Slugged slugs}. | |
| 187 187 | 
             
                #   allows an alternate configuration syntax, and conditional configuration
         | 
| 188 188 | 
             
                #   logic.
         | 
| 189 189 | 
             
                #
         | 
| 190 | 
            +
                # @option options [Symbol,Boolean] :dependent Available when using `:history`.
         | 
| 191 | 
            +
                #   Sets the value used for the slugged association's dependent option. Use
         | 
| 192 | 
            +
                #   `false` if you do not want to dependently destroy the associated slugged
         | 
| 193 | 
            +
                #   record. Defaults to `:destroy`.
         | 
| 194 | 
            +
                #
         | 
| 195 | 
            +
                # @option options [Symbol] :routes When set to anything other than :friendly,
         | 
| 196 | 
            +
                #   ensures that all routes generated by default do *not* use the slug.  This
         | 
| 197 | 
            +
                #   allows `form_for` and `polymorphic_path` to continue to generate paths like
         | 
| 198 | 
            +
                #   `/team/1` instead of `/team/number-one`.  You can still generate paths
         | 
| 199 | 
            +
                #   like the latter using: team_path(team.slug).  When set to :friendly, or
         | 
| 200 | 
            +
                #   omitted, the default friendly_id behavior is maintained.
         | 
| 201 | 
            +
                #
         | 
| 190 202 | 
             
                # @yieldparam config The model class's {FriendlyId::Configuration friendly_id_config}.
         | 
| 191 203 | 
             
                def friendly_id(base = nil, options = {}, &block)
         | 
| 192 204 | 
             
                  yield friendly_id_config if block_given?
         | 
| 205 | 
            +
                  friendly_id_config.dependent = options.delete :dependent
         | 
| 193 206 | 
             
                  friendly_id_config.use options.delete :use
         | 
| 194 207 | 
             
                  friendly_id_config.send :set, base ? options.merge(:base => base) : options
         | 
| 195 208 | 
             
                  include Model
         | 
| @@ -244,11 +257,15 @@ often better and easier to use {FriendlyId::Slugged slugs}. | |
| 244 257 |  | 
| 245 258 | 
             
                # Either the friendly_id, or the numeric id cast to a string.
         | 
| 246 259 | 
             
                def to_param
         | 
| 247 | 
            -
                  if  | 
| 248 | 
            -
                     | 
| 249 | 
            -
             | 
| 260 | 
            +
                  if friendly_id_config.routes == :friendly
         | 
| 261 | 
            +
                    if attribute_changed?(friendly_id_config.query_field)
         | 
| 262 | 
            +
                      diff = changes[friendly_id_config.query_field]
         | 
| 263 | 
            +
                      diff.first || diff.second
         | 
| 264 | 
            +
                    else
         | 
| 265 | 
            +
                      friendly_id.presence.to_param || super
         | 
| 266 | 
            +
                    end
         | 
| 250 267 | 
             
                  else
         | 
| 251 | 
            -
                     | 
| 268 | 
            +
                    super
         | 
| 252 269 | 
             
                  end
         | 
| 253 270 | 
             
                end
         | 
| 254 271 |  | 
| @@ -18,11 +18,18 @@ module FriendlyId | |
| 18 18 | 
             
                # The module to use for finders
         | 
| 19 19 | 
             
                attr_accessor :finder_methods
         | 
| 20 20 |  | 
| 21 | 
            +
                # The value used for the slugged association's dependent option
         | 
| 22 | 
            +
                attr_accessor :dependent
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                # Route generation preferences
         | 
| 25 | 
            +
                attr_accessor :routes
         | 
| 26 | 
            +
             | 
| 21 27 | 
             
                def initialize(model_class, values = nil)
         | 
| 22 28 | 
             
                  @model_class    = model_class
         | 
| 23 29 | 
             
                  @defaults       = {}
         | 
| 24 30 | 
             
                  @modules        = []
         | 
| 25 31 | 
             
                  @finder_methods = FriendlyId::FinderMethods
         | 
| 32 | 
            +
                  self.routes = :friendly
         | 
| 26 33 | 
             
                  set values
         | 
| 27 34 | 
             
                end
         | 
| 28 35 |  | 
| @@ -20,7 +20,7 @@ module FriendlyId | |
| 20 20 | 
             
                  return super if args.count != 1 || id.unfriendly_id?
         | 
| 21 21 | 
             
                  first_by_friendly_id(id).tap {|result| return result unless result.nil?}
         | 
| 22 22 | 
             
                  return super if potential_primary_key?(id)
         | 
| 23 | 
            -
                  raise ActiveRecord::RecordNotFound
         | 
| 23 | 
            +
                  raise ActiveRecord::RecordNotFound, "can't find record with friendly id: #{id.inspect}"
         | 
| 24 24 | 
             
                end
         | 
| 25 25 |  | 
| 26 26 | 
             
                # Returns true if a record with the given id exists.
         | 
| @@ -33,7 +33,7 @@ module FriendlyId | |
| 33 33 | 
             
                # `find`.
         | 
| 34 34 | 
             
                # @raise ActiveRecord::RecordNotFound
         | 
| 35 35 | 
             
                def find_by_friendly_id(id)
         | 
| 36 | 
            -
                  first_by_friendly_id(id) or raise ActiveRecord::RecordNotFound
         | 
| 36 | 
            +
                  first_by_friendly_id(id) or raise ActiveRecord::RecordNotFound, "can't find record with friendly id: #{id.inspect}"
         | 
| 37 37 | 
             
                end
         | 
| 38 38 |  | 
| 39 39 | 
             
                def exists_by_friendly_id?(id)
         | 
| @@ -54,8 +54,8 @@ module FriendlyId | |
| 54 54 | 
             
                end
         | 
| 55 55 |  | 
| 56 56 | 
             
                def first_by_friendly_id(id)
         | 
| 57 | 
            -
                   | 
| 57 | 
            +
                  find_by(friendly_id_config.query_field => id)
         | 
| 58 58 | 
             
                end
         | 
| 59 59 |  | 
| 60 60 | 
             
              end
         | 
| 61 | 
            -
            end
         | 
| 61 | 
            +
            end
         | 
    
        data/lib/friendly_id/finders.rb
    CHANGED
    
    | @@ -76,17 +76,14 @@ for models that use FriendlyId with something similar to the following: | |
| 76 76 | 
             
                def self.setup(model_class)
         | 
| 77 77 | 
             
                  model_class.instance_eval do
         | 
| 78 78 | 
             
                    relation.class.send(:include, friendly_id_config.finder_methods)
         | 
| 79 | 
            -
                    if ActiveRecord::VERSION::MAJOR == 4 && ActiveRecord::VERSION::MINOR == 2
         | 
| 79 | 
            +
                    if (ActiveRecord::VERSION::MAJOR == 4 && ActiveRecord::VERSION::MINOR == 2) || ActiveRecord::VERSION::MAJOR == 5
         | 
| 80 80 | 
             
                      model_class.send(:extend, friendly_id_config.finder_methods)
         | 
| 81 81 | 
             
                    end
         | 
| 82 82 | 
             
                  end
         | 
| 83 | 
            -
                end
         | 
| 84 | 
            -
             | 
| 85 | 
            -
                def self.included(model_class)
         | 
| 86 | 
            -
                  model_class.extend(ClassMethods)
         | 
| 87 83 |  | 
| 88 84 | 
             
                  # Support for friendly finds on associations for Rails 4.0.1 and above.
         | 
| 89 85 | 
             
                  if ::ActiveRecord.const_defined?('AssociationRelation')
         | 
| 86 | 
            +
                    model_class.extend(ClassMethods)
         | 
| 90 87 | 
             
                    association_relation_delegate_class = model_class.relation_delegate_class(::ActiveRecord::AssociationRelation)
         | 
| 91 88 | 
             
                    association_relation_delegate_class.send(:include, model_class.friendly_id_config.finder_methods)
         | 
| 92 89 | 
             
                  end
         | 
    
        data/lib/friendly_id/history.rb
    CHANGED
    
    | @@ -41,7 +41,7 @@ method. | |
| 41 41 | 
             
                  ...
         | 
| 42 42 |  | 
| 43 43 | 
             
                  def find_post
         | 
| 44 | 
            -
                    @post = Post.find params[:id]
         | 
| 44 | 
            +
                    @post = Post.friendly.find params[:id]
         | 
| 45 45 |  | 
| 46 46 | 
             
                    # If an old id or a numeric id was used to find the record, then
         | 
| 47 47 | 
             
                    # the request path will not match the post_path, and we should do
         | 
| @@ -54,16 +54,18 @@ method. | |
| 54 54 | 
             
            =end
         | 
| 55 55 | 
             
              module History
         | 
| 56 56 |  | 
| 57 | 
            +
                module Configuration
         | 
| 58 | 
            +
                  def dependent_value
         | 
| 59 | 
            +
                    dependent.nil? ? :destroy : dependent
         | 
| 60 | 
            +
                  end
         | 
| 61 | 
            +
                end
         | 
| 62 | 
            +
             | 
| 57 63 | 
             
                def self.setup(model_class)
         | 
| 58 64 | 
             
                  model_class.instance_eval do
         | 
| 59 65 | 
             
                    friendly_id_config.use :slugged
         | 
| 66 | 
            +
                    friendly_id_config.class.send :include, History::Configuration
         | 
| 60 67 | 
             
                    friendly_id_config.finder_methods = FriendlyId::History::FinderMethods
         | 
| 61 | 
            -
                    if friendly_id_config.uses? :finders
         | 
| 62 | 
            -
                      relation.class.send(:include, friendly_id_config.finder_methods)
         | 
| 63 | 
            -
                      if ActiveRecord::VERSION::MAJOR == 4 && ActiveRecord::VERSION::MINOR == 2
         | 
| 64 | 
            -
                        model_class.send(:extend, friendly_id_config.finder_methods)
         | 
| 65 | 
            -
                      end
         | 
| 66 | 
            -
                    end
         | 
| 68 | 
            +
                    FriendlyId::Finders.setup(model_class) if friendly_id_config.uses? :finders
         | 
| 67 69 | 
             
                  end
         | 
| 68 70 | 
             
                end
         | 
| 69 71 |  | 
| @@ -72,7 +74,7 @@ method. | |
| 72 74 | 
             
                  model_class.class_eval do
         | 
| 73 75 | 
             
                    has_many :slugs, -> {order("#{Slug.quoted_table_name}.id DESC")}, {
         | 
| 74 76 | 
             
                      :as         => :sluggable,
         | 
| 75 | 
            -
                      :dependent  =>  | 
| 77 | 
            +
                      :dependent  => @friendly_id_config.dependent_value,
         | 
| 76 78 | 
             
                      :class_name => Slug.to_s
         | 
| 77 79 | 
             
                    }
         | 
| 78 80 |  | 
| @@ -84,7 +86,7 @@ method. | |
| 84 86 | 
             
                  include ::FriendlyId::FinderMethods
         | 
| 85 87 |  | 
| 86 88 | 
             
                  def exists_by_friendly_id?(id)
         | 
| 87 | 
            -
                     | 
| 89 | 
            +
                    where(arel_table[friendly_id_config.query_field].eq(id)).exists? || joins(:slugs).where(slug_history_clause(id)).exists?
         | 
| 88 90 | 
             
                  end
         | 
| 89 91 |  | 
| 90 92 | 
             
                  private
         | 
| @@ -111,7 +113,7 @@ method. | |
| 111 113 | 
             
                def scope_for_slug_generator
         | 
| 112 114 | 
             
                  relation = super
         | 
| 113 115 | 
             
                  return relation if new_record?
         | 
| 114 | 
            -
                  relation = relation.merge(Slug.where('sluggable_id <> ?', id))
         | 
| 116 | 
            +
                  relation = relation.joins(:slugs).merge(Slug.where('sluggable_id <> ?', id))
         | 
| 115 117 | 
             
                  if friendly_id_config.uses?(:scoped)
         | 
| 116 118 | 
             
                    relation = relation.where(Slug.arel_table[:scope].eq(serialized_scope))
         | 
| 117 119 | 
             
                  end
         | 
| @@ -8,8 +8,8 @@ class CreateFriendlyIdSlugs < ActiveRecord::Migration | |
| 8 8 | 
             
                  t.datetime :created_at
         | 
| 9 9 | 
             
                end
         | 
| 10 10 | 
             
                add_index :friendly_id_slugs, :sluggable_id
         | 
| 11 | 
            -
                add_index :friendly_id_slugs, [:slug, :sluggable_type]
         | 
| 12 | 
            -
                add_index :friendly_id_slugs, [:slug, :sluggable_type, :scope], :unique  | 
| 11 | 
            +
                add_index :friendly_id_slugs, [:slug, :sluggable_type], length: { slug: 140, sluggable_type: 50 }
         | 
| 12 | 
            +
                add_index :friendly_id_slugs, [:slug, :sluggable_type, :scope], length: { slug: 70, sluggable_type: 50, scope: 70 }, unique: true
         | 
| 13 13 | 
             
                add_index :friendly_id_slugs, :sluggable_type
         | 
| 14 14 | 
             
              end
         | 
| 15 15 | 
             
            end
         | 
| @@ -1,4 +1,17 @@ | |
| 1 1 | 
             
            module FriendlyId
         | 
| 2 | 
            +
              # Instances of these classes will never be considered a friendly id.
         | 
| 3 | 
            +
              # @see FriendlyId::ObjectUtils#friendly_id
         | 
| 4 | 
            +
              UNFRIENDLY_CLASSES = [
         | 
| 5 | 
            +
                ActiveRecord::Base,
         | 
| 6 | 
            +
                Array,
         | 
| 7 | 
            +
                FalseClass,
         | 
| 8 | 
            +
                Hash,
         | 
| 9 | 
            +
                NilClass,
         | 
| 10 | 
            +
                Numeric,
         | 
| 11 | 
            +
                Symbol,
         | 
| 12 | 
            +
                TrueClass
         | 
| 13 | 
            +
              ]
         | 
| 14 | 
            +
             | 
| 2 15 | 
             
              # Utility methods for determining whether any object is a friendly id.
         | 
| 3 16 | 
             
              #
         | 
| 4 17 | 
             
              # Monkey-patching Object is a somewhat extreme measure not to be taken lightly
         | 
| @@ -27,13 +40,7 @@ module FriendlyId | |
| 27 40 | 
             
                #     "123".friendly_id?                #=> nil
         | 
| 28 41 | 
             
                #     "abc123".friendly_id?             #=> true
         | 
| 29 42 | 
             
                def friendly_id?
         | 
| 30 | 
            -
                   | 
| 31 | 
            -
                  # one of its descendants.
         | 
| 32 | 
            -
                  if FriendlyId::UNFRIENDLY_CLASSES.detect {|klass| self.class <= klass}
         | 
| 33 | 
            -
                    false
         | 
| 34 | 
            -
                  elsif respond_to?(:to_i) && to_i.to_s != to_s
         | 
| 35 | 
            -
                    true
         | 
| 36 | 
            -
                  end
         | 
| 43 | 
            +
                  true if respond_to?(:to_i) && to_i.to_s != to_s
         | 
| 37 44 | 
             
                end
         | 
| 38 45 |  | 
| 39 46 | 
             
                # True if the id is definitely unfriendly, false if definitely friendly,
         | 
| @@ -42,6 +49,21 @@ module FriendlyId | |
| 42 49 | 
             
                  val = friendly_id? ; !val unless val.nil?
         | 
| 43 50 | 
             
                end
         | 
| 44 51 | 
             
              end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
              module UnfriendlyUtils
         | 
| 54 | 
            +
                def friendly_id?
         | 
| 55 | 
            +
                  false
         | 
| 56 | 
            +
                end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                def unfriendly_id?
         | 
| 59 | 
            +
                  true
         | 
| 60 | 
            +
                end
         | 
| 61 | 
            +
              end
         | 
| 45 62 | 
             
            end
         | 
| 46 63 |  | 
| 47 64 | 
             
            Object.send :include, FriendlyId::ObjectUtils
         | 
| 65 | 
            +
             | 
| 66 | 
            +
            # Considered unfriendly if object is an instance of an unfriendly class or
         | 
| 67 | 
            +
            # one of its descendants.
         | 
| 68 | 
            +
             | 
| 69 | 
            +
            FriendlyId::UNFRIENDLY_CLASSES.each { |klass| klass.send(:include, FriendlyId::UnfriendlyUtils) }
         | 
| @@ -4,13 +4,11 @@ module FriendlyId | |
| 4 4 | 
             
                  model_class.friendly_id_config.use :slugged
         | 
| 5 5 | 
             
                end
         | 
| 6 6 |  | 
| 7 | 
            -
                def should_generate_new_friendly_id?
         | 
| 8 | 
            -
                  send(friendly_id_config.base).present? && super
         | 
| 9 | 
            -
                end
         | 
| 10 | 
            -
             | 
| 11 7 | 
             
                def resolve_friendly_id_conflict(candidate_slugs)
         | 
| 8 | 
            +
                  candidate = candidate_slugs.first
         | 
| 9 | 
            +
                  return if candidate.nil?
         | 
| 12 10 | 
             
                  SequentialSlugCalculator.new(scope_for_slug_generator,
         | 
| 13 | 
            -
                                               | 
| 11 | 
            +
                                              candidate,
         | 
| 14 12 | 
             
                                              friendly_id_config.slug_column,
         | 
| 15 13 | 
             
                                              friendly_id_config.sequence_separator).next_slug
         | 
| 16 14 | 
             
                end
         | 
| @@ -37,15 +37,15 @@ friendly_id_globalize gem instead. | |
| 37 37 | 
             
            Finds will take into consideration the current locale:
         | 
| 38 38 |  | 
| 39 39 | 
             
                I18n.locale = :es
         | 
| 40 | 
            -
                Post.find("la-guerra-de-las-galaxias")
         | 
| 40 | 
            +
                Post.friendly.find("la-guerra-de-las-galaxias")
         | 
| 41 41 | 
             
                I18n.locale = :en
         | 
| 42 | 
            -
                Post.find("star-wars")
         | 
| 42 | 
            +
                Post.friendly.find("star-wars")
         | 
| 43 43 |  | 
| 44 44 | 
             
            To find a slug by an explicit locale, perform the find inside a block
         | 
| 45 45 | 
             
            passed to I18n's `with_locale` method:
         | 
| 46 46 |  | 
| 47 47 | 
             
                I18n.with_locale(:es) do
         | 
| 48 | 
            -
                  Post.find("la-guerra-de-las-galaxias")
         | 
| 48 | 
            +
                  Post.friendly.find("la-guerra-de-las-galaxias")
         | 
| 49 49 | 
             
                end
         | 
| 50 50 |  | 
| 51 51 | 
             
            ### Creating Records
         | 
    
        data/lib/friendly_id/slugged.rb
    CHANGED
    
    
    
        data/lib/friendly_id/version.rb
    CHANGED
    
    
| @@ -0,0 +1,88 @@ | |
| 1 | 
            +
            require File.expand_path("../../helper", __FILE__)
         | 
| 2 | 
            +
            require "ffaker"
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            # This benchmark tests ActiveRecord and FriendlyId methods for performing a find
         | 
| 5 | 
            +
            #
         | 
| 6 | 
            +
            # ActiveRecord: where.first                     8.970000   0.040000   9.010000 (  9.029544)
         | 
| 7 | 
            +
            # ActiveRecord: where.take                      8.100000   0.030000   8.130000 (  8.157024)
         | 
| 8 | 
            +
            # ActiveRecord: find                            2.720000   0.010000   2.730000 (  2.733527)
         | 
| 9 | 
            +
            # ActiveRecord: find_by(:id)                    2.920000   0.000000   2.920000 (  2.926318)
         | 
| 10 | 
            +
            # ActiveRecord: find_by(:slug)                  2.650000   0.020000   2.670000 (  2.662677)
         | 
| 11 | 
            +
            # FriendlyId: find (in-table slug w/ finders)   9.820000   0.030000   9.850000 (  9.873358)
         | 
| 12 | 
            +
            # FriendlyId: friendly.find (in-table slug)    12.890000   0.050000  12.940000 ( 12.951156)
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            N = 50000
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            def transaction
         | 
| 17 | 
            +
              ActiveRecord::Base.transaction { yield ; raise ActiveRecord::Rollback }
         | 
| 18 | 
            +
            end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
            class Array
         | 
| 21 | 
            +
              def rand
         | 
| 22 | 
            +
                self[Kernel.rand(length)]
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
            end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
            Book = Class.new ActiveRecord::Base
         | 
| 27 | 
            +
             | 
| 28 | 
            +
            class Journalist < ActiveRecord::Base
         | 
| 29 | 
            +
              extend FriendlyId
         | 
| 30 | 
            +
              friendly_id :name, :use => :slugged
         | 
| 31 | 
            +
            end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
            class Manual < ActiveRecord::Base
         | 
| 34 | 
            +
              extend FriendlyId
         | 
| 35 | 
            +
              friendly_id :name, :use => :history
         | 
| 36 | 
            +
            end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
            class Restaurant < ActiveRecord::Base
         | 
| 39 | 
            +
              extend FriendlyId
         | 
| 40 | 
            +
              friendly_id :name, :use => :finders
         | 
| 41 | 
            +
            end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
             | 
| 44 | 
            +
            BOOKS       = []
         | 
| 45 | 
            +
            JOURNALISTS = []
         | 
| 46 | 
            +
            MANUALS     = []
         | 
| 47 | 
            +
            RESTAURANTS = []
         | 
| 48 | 
            +
             | 
| 49 | 
            +
            100.times do
         | 
| 50 | 
            +
              name = FFaker::Name.name
         | 
| 51 | 
            +
              BOOKS       << (Book.create! :name => name).id
         | 
| 52 | 
            +
              JOURNALISTS << (Journalist.create! :name => name).friendly_id
         | 
| 53 | 
            +
              MANUALS     << (Manual.create! :name => name).friendly_id
         | 
| 54 | 
            +
              RESTAURANTS << (Restaurant.create! :name => name).friendly_id
         | 
| 55 | 
            +
            end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
            ActiveRecord::Base.connection.execute "UPDATE manuals SET slug = NULL"
         | 
| 58 | 
            +
             | 
| 59 | 
            +
            Benchmark.bmbm do |x|
         | 
| 60 | 
            +
              x.report 'ActiveRecord: where.first' do
         | 
| 61 | 
            +
                N.times {Book.where(:id=>BOOKS.rand).first}
         | 
| 62 | 
            +
              end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
              x.report 'ActiveRecord: where.take' do
         | 
| 65 | 
            +
                N.times {Book.where(:id=>BOOKS.rand).take}
         | 
| 66 | 
            +
              end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
              x.report 'ActiveRecord: find' do
         | 
| 69 | 
            +
                N.times {Book.find BOOKS.rand}
         | 
| 70 | 
            +
              end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
              x.report 'ActiveRecord: find_by(:id)' do
         | 
| 73 | 
            +
                N.times {Book.find_by(:id=>BOOKS.rand)}
         | 
| 74 | 
            +
              end
         | 
| 75 | 
            +
             | 
| 76 | 
            +
              x.report 'ActiveRecord: find_by(:slug)' do
         | 
| 77 | 
            +
                N.times {Restaurant.find_by(:slug=>RESTAURANTS.rand)}
         | 
| 78 | 
            +
              end
         | 
| 79 | 
            +
             | 
| 80 | 
            +
              x.report 'FriendlyId: find (in-table slug w/ finders)' do
         | 
| 81 | 
            +
                N.times {Restaurant.find RESTAURANTS.rand}
         | 
| 82 | 
            +
              end
         | 
| 83 | 
            +
             | 
| 84 | 
            +
              x.report 'FriendlyId: friendly.find (in-table slug)' do
         | 
| 85 | 
            +
                N.times {Restaurant.friendly.find RESTAURANTS.rand}
         | 
| 86 | 
            +
              end
         | 
| 87 | 
            +
             | 
| 88 | 
            +
            end
         | 
| @@ -0,0 +1,56 @@ | |
| 1 | 
            +
            require File.expand_path("../../helper", __FILE__)
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            # This benchmark compares the timings of the friendly_id? and unfriendly_id? on various objects
         | 
| 4 | 
            +
            #
         | 
| 5 | 
            +
            # integer friendly_id?            6.370000   0.000000   6.370000 (  6.380925)
         | 
| 6 | 
            +
            # integer unfriendly_id?          6.640000   0.010000   6.650000 (  6.646057)
         | 
| 7 | 
            +
            # AR::Base friendly_id?           2.340000   0.000000   2.340000 (  2.340743)
         | 
| 8 | 
            +
            # AR::Base unfriendly_id?         2.560000   0.000000   2.560000 (  2.560039)
         | 
| 9 | 
            +
            # hash friendly_id?               5.090000   0.010000   5.100000 (  5.097662)
         | 
| 10 | 
            +
            # hash unfriendly_id?             5.430000   0.000000   5.430000 (  5.437160)
         | 
| 11 | 
            +
            # nil friendly_id?                5.610000   0.010000   5.620000 (  5.611487)
         | 
| 12 | 
            +
            # nil unfriendly_id?              5.870000   0.000000   5.870000 (  5.880484)
         | 
| 13 | 
            +
            # numeric string friendly_id?     9.270000   0.030000   9.300000 (  9.308452)
         | 
| 14 | 
            +
            # numeric string unfriendly_id?   9.190000   0.040000   9.230000 (  9.252890)
         | 
| 15 | 
            +
            # test_string friendly_id?        8.380000   0.010000   8.390000 (  8.411762)
         | 
| 16 | 
            +
            # test_string unfriendly_id?      8.450000   0.010000   8.460000 (  8.463662)
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            # From the ObjectUtils docs...
         | 
| 19 | 
            +
            #     123.friendly_id?                  #=> false
         | 
| 20 | 
            +
            #     :id.friendly_id?                  #=> false
         | 
| 21 | 
            +
            #     {:name => 'joe'}.friendly_id?     #=> false
         | 
| 22 | 
            +
            #     ['name = ?', 'joe'].friendly_id?  #=> false
         | 
| 23 | 
            +
            #     nil.friendly_id?                  #=> false
         | 
| 24 | 
            +
            #     "123".friendly_id?                #=> nil
         | 
| 25 | 
            +
            #     "abc123".friendly_id?             #=> true
         | 
| 26 | 
            +
             | 
| 27 | 
            +
            Book = Class.new ActiveRecord::Base
         | 
| 28 | 
            +
             | 
| 29 | 
            +
            test_integer = 123
         | 
| 30 | 
            +
            test_active_record_object = Book.new
         | 
| 31 | 
            +
            test_hash = {:name=>'joe'}
         | 
| 32 | 
            +
            test_nil = nil
         | 
| 33 | 
            +
            test_numeric_string = "123"
         | 
| 34 | 
            +
            test_string = "abc123"
         | 
| 35 | 
            +
             | 
| 36 | 
            +
            N = 5_000_000
         | 
| 37 | 
            +
             | 
| 38 | 
            +
            Benchmark.bmbm do |x|
         | 
| 39 | 
            +
              x.report('integer friendly_id?') { N.times {test_integer.friendly_id?} }
         | 
| 40 | 
            +
              x.report('integer unfriendly_id?') { N.times {test_integer.unfriendly_id?} }
         | 
| 41 | 
            +
             | 
| 42 | 
            +
              x.report('AR::Base friendly_id?') { N.times {test_active_record_object.friendly_id?} }
         | 
| 43 | 
            +
              x.report('AR::Base unfriendly_id?') { N.times {test_active_record_object.unfriendly_id?} }
         | 
| 44 | 
            +
             | 
| 45 | 
            +
              x.report('hash friendly_id?') { N.times {test_hash.friendly_id?} }
         | 
| 46 | 
            +
              x.report('hash unfriendly_id?') { N.times {test_hash.unfriendly_id?} }
         | 
| 47 | 
            +
             | 
| 48 | 
            +
              x.report('nil friendly_id?') { N.times {test_nil.friendly_id?} }
         | 
| 49 | 
            +
              x.report('nil unfriendly_id?') { N.times {test_nil.unfriendly_id?} }
         | 
| 50 | 
            +
             | 
| 51 | 
            +
              x.report('numeric string friendly_id?') { N.times {test_numeric_string.friendly_id?} }
         | 
| 52 | 
            +
              x.report('numeric string unfriendly_id?') { N.times {test_numeric_string.unfriendly_id?} }
         | 
| 53 | 
            +
             | 
| 54 | 
            +
              x.report('test_string friendly_id?') { N.times {test_string.friendly_id?} }
         | 
| 55 | 
            +
              x.report('test_string unfriendly_id?') { N.times {test_string.unfriendly_id?} }
         | 
| 56 | 
            +
            end
         | 
    
        data/test/history_test.rb
    CHANGED
    
    | @@ -1,15 +1,15 @@ | |
| 1 1 | 
             
            require "helper"
         | 
| 2 2 |  | 
| 3 | 
            -
            class Manual < ActiveRecord::Base
         | 
| 4 | 
            -
              extend FriendlyId
         | 
| 5 | 
            -
              friendly_id :name, :use => [:slugged, :history]
         | 
| 6 | 
            -
            end
         | 
| 7 | 
            -
             | 
| 8 3 | 
             
            class HistoryTest < TestCaseClass
         | 
| 9 4 |  | 
| 10 5 | 
             
              include FriendlyId::Test
         | 
| 11 6 | 
             
              include FriendlyId::Test::Shared::Core
         | 
| 12 7 |  | 
| 8 | 
            +
              class Manual < ActiveRecord::Base
         | 
| 9 | 
            +
                extend FriendlyId
         | 
| 10 | 
            +
                friendly_id :name, :use => [:slugged, :history]
         | 
| 11 | 
            +
              end
         | 
| 12 | 
            +
             | 
| 13 13 | 
             
              def model_class
         | 
| 14 14 | 
             
                Manual
         | 
| 15 15 | 
             
              end
         | 
| @@ -172,6 +172,45 @@ class HistoryTestWithAutomaticSlugRegeneration < HistoryTest | |
| 172 172 | 
             
              end
         | 
| 173 173 | 
             
            end
         | 
| 174 174 |  | 
| 175 | 
            +
            class DependentDestroyTest < HistoryTest
         | 
| 176 | 
            +
             | 
| 177 | 
            +
              include FriendlyId::Test
         | 
| 178 | 
            +
             | 
| 179 | 
            +
              class FalseManual < ActiveRecord::Base
         | 
| 180 | 
            +
                self.table_name = 'manuals'
         | 
| 181 | 
            +
             | 
| 182 | 
            +
                extend FriendlyId
         | 
| 183 | 
            +
                friendly_id :name, :use => :history, :dependent => false
         | 
| 184 | 
            +
              end
         | 
| 185 | 
            +
             | 
| 186 | 
            +
              class DefaultManual < ActiveRecord::Base
         | 
| 187 | 
            +
                self.table_name = 'manuals'
         | 
| 188 | 
            +
             | 
| 189 | 
            +
                extend FriendlyId
         | 
| 190 | 
            +
                friendly_id :name, :use => :history
         | 
| 191 | 
            +
              end
         | 
| 192 | 
            +
             | 
| 193 | 
            +
              test 'should allow disabling of dependent destroy' do
         | 
| 194 | 
            +
                transaction do
         | 
| 195 | 
            +
                  assert FriendlyId::Slug.find_by_slug('foo').nil?
         | 
| 196 | 
            +
                  l = FalseManual.create! :name => 'foo'
         | 
| 197 | 
            +
                  assert FriendlyId::Slug.find_by_slug('foo').present?
         | 
| 198 | 
            +
                  l.destroy
         | 
| 199 | 
            +
                  assert FriendlyId::Slug.find_by_slug('foo').present?
         | 
| 200 | 
            +
                end
         | 
| 201 | 
            +
              end
         | 
| 202 | 
            +
             | 
| 203 | 
            +
              test 'should dependently destroy by default' do
         | 
| 204 | 
            +
                transaction do
         | 
| 205 | 
            +
                  assert FriendlyId::Slug.find_by_slug('baz').nil?
         | 
| 206 | 
            +
                  l = DefaultManual.create! :name => 'baz'
         | 
| 207 | 
            +
                  assert FriendlyId::Slug.find_by_slug('baz').present?
         | 
| 208 | 
            +
                  l.destroy
         | 
| 209 | 
            +
                  assert FriendlyId::Slug.find_by_slug('baz').nil?
         | 
| 210 | 
            +
                end
         | 
| 211 | 
            +
              end
         | 
| 212 | 
            +
            end
         | 
| 213 | 
            +
             | 
| 175 214 | 
             
            class HistoryTestWithSti < HistoryTest
         | 
| 176 215 | 
             
              class Journalist < ActiveRecord::Base
         | 
| 177 216 | 
             
                extend FriendlyId
         | 
| @@ -217,6 +256,36 @@ class HistoryTestWithFriendlyFinders < HistoryTest | |
| 217 256 | 
             
              end
         | 
| 218 257 | 
             
            end
         | 
| 219 258 |  | 
| 259 | 
            +
            class HistoryTestWithFindersBeforeHistory < HistoryTest
         | 
| 260 | 
            +
              class Novelist < ActiveRecord::Base
         | 
| 261 | 
            +
                has_many :novels
         | 
| 262 | 
            +
              end
         | 
| 263 | 
            +
             | 
| 264 | 
            +
              class Novel < ActiveRecord::Base
         | 
| 265 | 
            +
                extend FriendlyId
         | 
| 266 | 
            +
             | 
| 267 | 
            +
                belongs_to :novelist
         | 
| 268 | 
            +
             | 
| 269 | 
            +
                friendly_id :name, :use => [:finders, :history]
         | 
| 270 | 
            +
             | 
| 271 | 
            +
                def should_generate_new_friendly_id?
         | 
| 272 | 
            +
                  slug.blank? || name_changed?
         | 
| 273 | 
            +
                end
         | 
| 274 | 
            +
              end
         | 
| 275 | 
            +
             | 
| 276 | 
            +
              test "should be findable by old slug through has_many association" do
         | 
| 277 | 
            +
                transaction do
         | 
| 278 | 
            +
                  novelist = Novelist.create!(:name => "Stephen King")
         | 
| 279 | 
            +
                  novel = novelist.novels.create(:name => "Rita Hayworth and Shawshank Redemption")
         | 
| 280 | 
            +
                  slug = novel.slug
         | 
| 281 | 
            +
                  novel.name = "Shawshank Redemption"
         | 
| 282 | 
            +
                  novel.save!
         | 
| 283 | 
            +
                  assert_equal novel, Novel.find(slug)
         | 
| 284 | 
            +
                  assert_equal novel, novelist.novels.find(slug)
         | 
| 285 | 
            +
                end
         | 
| 286 | 
            +
              end
         | 
| 287 | 
            +
            end
         | 
| 288 | 
            +
             | 
| 220 289 | 
             
            class City < ActiveRecord::Base
         | 
| 221 290 | 
             
              has_many :restaurants
         | 
| 222 291 | 
             
            end
         | 
| @@ -89,6 +89,22 @@ class SequentiallySluggedTest < TestCaseClass | |
| 89 89 | 
             
                end
         | 
| 90 90 | 
             
              end
         | 
| 91 91 |  | 
| 92 | 
            +
              test "should not generate a slug when canidates set is empty" do
         | 
| 93 | 
            +
                model_class = Class.new(ActiveRecord::Base) do
         | 
| 94 | 
            +
                  self.table_name = "cities"
         | 
| 95 | 
            +
                  extend FriendlyId
         | 
| 96 | 
            +
                  friendly_id :slug_candidates, :use => [ :sequentially_slugged ]
         | 
| 97 | 
            +
             | 
| 98 | 
            +
                  def slug_candidates
         | 
| 99 | 
            +
                    [name, [name, code]]
         | 
| 100 | 
            +
                  end
         | 
| 101 | 
            +
                end
         | 
| 102 | 
            +
                transaction do
         | 
| 103 | 
            +
                  record = model_class.create!(:name => nil, :code => nil)
         | 
| 104 | 
            +
                  assert_nil record.slug
         | 
| 105 | 
            +
                end
         | 
| 106 | 
            +
              end
         | 
| 107 | 
            +
             | 
| 92 108 | 
             
              test "should not generate a slug when the sluggable attribute is blank" do
         | 
| 93 109 | 
             
                record = model_class.create!(:name => '')
         | 
| 94 110 | 
             
                assert_nil record.slug
         | 
    
        data/test/slugged_test.rb
    CHANGED
    
    | @@ -373,3 +373,35 @@ class FailedValidationAfterUpdateRegressionTest < TestCaseClass | |
| 373 373 | 
             
              end
         | 
| 374 374 |  | 
| 375 375 | 
             
            end
         | 
| 376 | 
            +
             | 
| 377 | 
            +
            class ConfigurableRoutesTest < TestCaseClass
         | 
| 378 | 
            +
              include FriendlyId::Test
         | 
| 379 | 
            +
             | 
| 380 | 
            +
              class Article < ActiveRecord::Base
         | 
| 381 | 
            +
                extend FriendlyId
         | 
| 382 | 
            +
             | 
| 383 | 
            +
                friendly_id :name, :use => :slugged, :routes => :friendly
         | 
| 384 | 
            +
              end
         | 
| 385 | 
            +
             | 
| 386 | 
            +
              class Novel < ActiveRecord::Base
         | 
| 387 | 
            +
                extend FriendlyId
         | 
| 388 | 
            +
             | 
| 389 | 
            +
                friendly_id :name, :use => :slugged, :routes => :default
         | 
| 390 | 
            +
              end
         | 
| 391 | 
            +
             | 
| 392 | 
            +
              test "to_param should return a friendly id when the routes option is set to :friendly" do
         | 
| 393 | 
            +
                transaction do
         | 
| 394 | 
            +
                  article = Article.create! :name => "Titanic Hits; Iceberg Sinks"
         | 
| 395 | 
            +
             | 
| 396 | 
            +
                  assert_equal "titanic-hits-iceberg-sinks", article.to_param
         | 
| 397 | 
            +
                end
         | 
| 398 | 
            +
              end
         | 
| 399 | 
            +
             | 
| 400 | 
            +
              test "to_param should return the id when the routes option is set to anything but friendly" do
         | 
| 401 | 
            +
                transaction do
         | 
| 402 | 
            +
                  novel = Novel.create! :name => "Don Quixote"
         | 
| 403 | 
            +
             | 
| 404 | 
            +
                  assert_equal novel.id.to_s, novel.to_param
         | 
| 405 | 
            +
                end
         | 
| 406 | 
            +
              end
         | 
| 407 | 
            +
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: friendly_id
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 5.2.0 | 
| 4 | 
            +
              version: 5.2.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Norman Clarke
         | 
| @@ -9,7 +9,7 @@ authors: | |
| 9 9 | 
             
            autorequire: 
         | 
| 10 10 | 
             
            bindir: bin
         | 
| 11 11 | 
             
            cert_chain: []
         | 
| 12 | 
            -
            date:  | 
| 12 | 
            +
            date: 2016-12-01 00:00:00.000000000 Z
         | 
| 13 13 | 
             
            dependencies:
         | 
| 14 14 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 15 15 | 
             
              name: activerecord
         | 
| @@ -163,6 +163,7 @@ files: | |
| 163 163 | 
             
            - gemfiles/Gemfile.rails-4.0.rb
         | 
| 164 164 | 
             
            - gemfiles/Gemfile.rails-4.1.rb
         | 
| 165 165 | 
             
            - gemfiles/Gemfile.rails-4.2.rb
         | 
| 166 | 
            +
            - gemfiles/Gemfile.rails-5.0.rb
         | 
| 166 167 | 
             
            - guide.rb
         | 
| 167 168 | 
             
            - lib/friendly_id.rb
         | 
| 168 169 | 
             
            - lib/friendly_id/.gitattributes
         | 
| @@ -185,6 +186,8 @@ files: | |
| 185 186 | 
             
            - lib/friendly_id/version.rb
         | 
| 186 187 | 
             
            - lib/generators/friendly_id_generator.rb
         | 
| 187 188 | 
             
            - test/base_test.rb
         | 
| 189 | 
            +
            - test/benchmarks/finders.rb
         | 
| 190 | 
            +
            - test/benchmarks/object_utils.rb
         | 
| 188 191 | 
             
            - test/candidates_test.rb
         | 
| 189 192 | 
             
            - test/configuration_test.rb
         | 
| 190 193 | 
             
            - test/core_test.rb
         | 
| @@ -202,7 +205,7 @@ files: | |
| 202 205 | 
             
            - test/simple_i18n_test.rb
         | 
| 203 206 | 
             
            - test/slugged_test.rb
         | 
| 204 207 | 
             
            - test/sti_test.rb
         | 
| 205 | 
            -
            homepage:  | 
| 208 | 
            +
            homepage: https://github.com/norman/friendly_id
         | 
| 206 209 | 
             
            licenses:
         | 
| 207 210 | 
             
            - MIT
         | 
| 208 211 | 
             
            metadata: {}
         | 
| @@ -217,14 +220,13 @@ required_ruby_version: !ruby/object:Gem::Requirement | |
| 217 220 | 
             
                  version: 1.9.3
         | 
| 218 221 | 
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 219 222 | 
             
              requirements:
         | 
| 220 | 
            -
              - - " | 
| 223 | 
            +
              - - ">="
         | 
| 221 224 | 
             
                - !ruby/object:Gem::Version
         | 
| 222 | 
            -
                  version:  | 
| 225 | 
            +
                  version: '0'
         | 
| 223 226 | 
             
            requirements: []
         | 
| 224 227 | 
             
            rubyforge_project: friendly_id
         | 
| 225 | 
            -
            rubygems_version: 2. | 
| 228 | 
            +
            rubygems_version: 2.5.2
         | 
| 226 229 | 
             
            signing_key: 
         | 
| 227 230 | 
             
            specification_version: 4
         | 
| 228 231 | 
             
            summary: A comprehensive slugging and pretty-URL plugin.
         | 
| 229 232 | 
             
            test_files: []
         | 
| 230 | 
            -
            has_rdoc: 
         |