diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d6dc685..cb8bf9c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -3,9 +3,22 @@ name: CI RSpec Test on: [push, pull_request] jobs: + rubocop: + runs-on: ubuntu-latest + env: + CI: true + steps: + - uses: actions/checkout@v3 + - name: Set up Ruby 3.4 + uses: ruby/setup-ruby@v1 + with: + ruby-version: 3.4 + bundler-cache: true + - name: Run RuboCop + run: bundle exec rubocop --parallel + build: - name: >- - ${{ matrix.ruby }} + name: "${{ matrix.ruby }} mongoid-${{ matrix.mongoid }}" env: CI: true TESTOPTS: -v @@ -14,18 +27,28 @@ jobs: strategy: fail-fast: false matrix: - ruby: [2.7, 3.0, 3.1, 3.2, truffleruby] - mongoid: [7, 8] + ruby: + - ruby-2.7 + - ruby-3.0 + - ruby-3.1 + - ruby-3.2 + - ruby-3.3 + - ruby-3.4 + - truffleruby + mongoid: + - '8.0' + - '8.1' + - '9.0' experimental: [false] include: - - ruby: 3.2 - mongoid: HEAD + - ruby: ruby-3.2 + mongoid: head experimental: true - - ruby: head + - ruby: ruby-head mongoid: 7 experimental: true - - ruby: head - mongoid: HEAD + - ruby: ruby-head + mongoid: head experimental: true - ruby: jruby mongoid: 8 @@ -58,13 +81,6 @@ jobs: env: MONGOID_VERSION: ${{ matrix.mongoid }} - - name: rubocop - timeout-minutes: 5 - run: bundle exec rubocop - continue-on-error: ${{ matrix.experimental }} - env: - MONGOID_VERSION: ${{ matrix.mongoid }} - - name: test timeout-minutes: 10 run: bundle exec rake spec diff --git a/.rubocop.yml b/.rubocop.yml index d9984b6..411beaf 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -29,6 +29,9 @@ Style/Documentation: Style/DoubleNegation: Enabled: false +Style/FetchEnvVar: + Enabled: false + Style/ModuleFunction: EnforcedStyle: extend_self diff --git a/Gemfile b/Gemfile index 17ccaec..c4faa6b 100644 --- a/Gemfile +++ b/Gemfile @@ -4,12 +4,12 @@ source 'https://rubygems.org' gemspec name: 'mongoid-slug' -case (version = ENV['MONGOID_VERSION'] || '8') -when 'HEAD' +case (version = ENV['MONGOID_VERSION'])&.downcase +when 'head' gem 'mongoid', github: 'mongodb/mongoid' -when /\A\d+\z/ +when /\A\d+(?:\.\d+)?\z/ gem 'mongoid', "~> #{version}.0" -else +when String gem 'mongoid', version end diff --git a/lib/mongoid/slug.rb b/lib/mongoid/slug.rb index 1f34b49..81234d3 100644 --- a/lib/mongoid/slug.rb +++ b/lib/mongoid/slug.rb @@ -79,7 +79,7 @@ def slug(*fields, &block) options = fields.extract_options! self.slug_scope = options[:scope] - self.slug_index = options[:index].nil? ? true : options[:index] + self.slug_index = options[:index].nil? || options[:index] self.slug_reserved_words = options[:reserve] || Set.new(%w[new edit]) self.slugged_attributes = fields.map(&:to_s) self.slug_history = options[:history] diff --git a/lib/mongoid/slug/criteria.rb b/lib/mongoid/slug/criteria.rb index 09b7de4..80ca7fd 100644 --- a/lib/mongoid/slug/criteria.rb +++ b/lib/mongoid/slug/criteria.rb @@ -26,11 +26,13 @@ class Criteria < Mongoid::Criteria # @example Find by multiple slugs. # criteria.find([ 'some-slug', 'some-other-slug' ]) # - # @param [ Array ] args The ids or slugs to search for. + # @param [ Array ] slugs The ids or slugs to search for. # # @return [ Array, Document ] The matching document(s). - def find(*args) - look_like_slugs?(args.__find_args__) ? find_by_slug!(*args) : super + def find(*slugs) + return find_by_slug!(*slugs) if look_like_slugs?(*slugs) + + super end # Find the matchind document(s) in the criteria for the provided slugs. @@ -41,21 +43,22 @@ def find(*args) # @example Find by multiple slugs. # criteria.find([ 'some-slug', 'some-other-slug' ]) # - # @param [ Array ] args The slugs to search for. + # @param [ Array... ] slugs The slugs to search for. # # @return [ Array, Document ] The matching document(s). - def find_by_slug!(*args) - slugs = args.__find_args__ + def find_by_slug!(*slugs) + slugs = find_args(slugs) raise_invalid if slugs.any?(&:nil?) - for_slugs(slugs).execute_or_raise_for_slugs(slugs, args.multi_arged?) + for_slugs(slugs).execute_or_raise_for_slugs(slugs) end - def look_like_slugs?(args) - return false unless args.all? { |id| id.is_a?(String) } + def look_like_slugs?(*slugs) + slugs = find_args(slugs) + return false unless slugs.all?(String) id_field = @klass.fields['_id'] @slug_strategy ||= id_field.options[:slug_id_strategy] || build_slug_strategy(id_field.type) - args.none? { |id| @slug_strategy.call(id) } + slugs.none? { |slug| @slug_strategy.call(slug) } end protected @@ -94,10 +97,16 @@ def for_slugs(slugs) end end - def execute_or_raise_for_slugs(slugs, multi) + def find_args(args) + args = args.flatten + args.uniq!(&:to_s) + args + end + + def execute_or_raise_for_slugs(slugs) result = uniq check_for_missing_documents_for_slugs!(result, slugs) - multi ? result : result.first + slugs.size == 1 ? result.first : result end def check_for_missing_documents_for_slugs!(result, slugs) diff --git a/lib/mongoid/slug/unique_slug.rb b/lib/mongoid/slug/unique_slug.rb index 3132129..f79bd8f 100644 --- a/lib/mongoid/slug/unique_slug.rb +++ b/lib/mongoid/slug/unique_slug.rb @@ -44,9 +44,8 @@ def highest_existing_counter def sort_existing_slugs # remove the slug part and leave the absolute integer part and sort - re = /^#{Regexp.escape(@slug)}/ @sorted_existing = existing_slugs.map do |s| - s.sub(re, '').to_i.abs + s.delete_prefix(@slug).to_i.abs end.sort end