slugs 1.3.2 → 2.0.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.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +1 -1
  3. data/Rakefile +5 -0
  4. data/lib/slugs.rb +36 -4
  5. data/lib/slugs/concern.rb +50 -0
  6. data/lib/slugs/configuration.rb +7 -0
  7. data/lib/slugs/extensions/action_dispatch/generator.rb +24 -0
  8. data/lib/slugs/extensions/action_dispatch/optimized_url_helper.rb +20 -0
  9. data/lib/slugs/extensions/active_record/base.rb +19 -0
  10. data/lib/slugs/railtie.rb +9 -1
  11. data/lib/slugs/version.rb +1 -1
  12. data/test/dummy/Rakefile +1 -2
  13. data/test/dummy/app/assets/javascripts/application.js +2 -2
  14. data/test/dummy/app/assets/stylesheets/application.css +6 -4
  15. data/test/dummy/app/models/category.rb +7 -0
  16. data/test/dummy/app/models/product.rb +8 -0
  17. data/test/dummy/app/models/shop.rb +5 -0
  18. data/test/dummy/app/models/user.rb +5 -0
  19. data/test/dummy/app/views/layouts/application.html.erb +9 -11
  20. data/test/dummy/bin/bundle +0 -0
  21. data/test/dummy/bin/rails +1 -1
  22. data/test/dummy/bin/rake +0 -0
  23. data/test/dummy/bin/setup +29 -0
  24. data/test/dummy/config.ru +1 -1
  25. data/test/dummy/config/application.rb +3 -1
  26. data/test/dummy/config/boot.rb +1 -1
  27. data/test/dummy/config/database.yml +4 -22
  28. data/test/dummy/config/database.yml.travis +12 -0
  29. data/test/dummy/config/environment.rb +1 -1
  30. data/test/dummy/config/environments/development.rb +14 -2
  31. data/test/dummy/config/environments/production.rb +20 -25
  32. data/test/dummy/config/environments/test.rb +8 -10
  33. data/test/dummy/config/initializers/assets.rb +11 -0
  34. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  35. data/test/dummy/config/initializers/mime_types.rb +1 -2
  36. data/test/dummy/config/initializers/session_store.rb +1 -1
  37. data/test/dummy/config/initializers/slugs.rb +5 -0
  38. data/test/dummy/config/routes.rb +2 -53
  39. data/test/dummy/config/secrets.yml +22 -0
  40. data/test/dummy/db/migrate/20161016174020_create_users.rb +9 -0
  41. data/test/dummy/db/migrate/20161016174126_create_shops.rb +8 -0
  42. data/test/dummy/db/migrate/20161016174202_create_products.rb +10 -0
  43. data/test/dummy/db/migrate/20161016174225_create_categories.rb +9 -0
  44. data/test/dummy/db/schema.rb +21 -26
  45. data/test/dummy/log/development.log +144 -0
  46. data/test/dummy/log/test.log +4190 -0
  47. data/test/dummy/public/404.html +20 -11
  48. data/test/dummy/public/422.html +20 -11
  49. data/test/dummy/public/500.html +19 -10
  50. data/test/records_test.rb +15 -103
  51. data/test/routes_test.rb +17 -0
  52. data/test/test_helper.rb +4 -12
  53. metadata +49 -54
  54. data/lib/slugs/active_record/base.rb +0 -82
  55. data/lib/slugs/active_record/finders.rb +0 -24
  56. data/lib/slugs/active_record/non_translatable.rb +0 -26
  57. data/lib/slugs/active_record/translatable.rb +0 -49
  58. data/test/dummy/README.rdoc +0 -28
  59. data/test/dummy/app/models/simple.rb +0 -5
  60. data/test/dummy/app/models/translatable.rb +0 -7
  61. data/test/dummy/app/models/translatable_translation.rb +0 -8
  62. data/test/dummy/app/models/without.rb +0 -2
  63. data/test/dummy/config/initializers/secret_token.rb +0 -13
  64. data/test/dummy/db/migrate/20130819183013_create_simples.rb +0 -11
  65. data/test/dummy/db/migrate/20130819183047_create_withouts.rb +0 -9
  66. data/test/dummy/db/migrate/20130819183119_create_translatables.rb +0 -8
  67. data/test/dummy/db/migrate/20130819183257_create_translatable_translations.rb +0 -15
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: da5d1fa47f7e6e409576151a4968039e74a17100
4
- data.tar.gz: 0361f871473aebf05e89564fc51ea8854ce78a85
3
+ metadata.gz: ed7eaf4b4b662abd59ca80f68a4b0eb218a8e112
4
+ data.tar.gz: f6b020ad3fbb60c5975c739831edab4becfe0f73
5
5
  SHA512:
6
- metadata.gz: 10daebc764de1a327d05eabb6db3d5b80965501202331ce85bce8df271fe6354bf1f050dcdbd6baee2885f1bc0ac79be932f94df448e41bba8b27c6927c96ecf
7
- data.tar.gz: 110090ea40a80b8df582caf2dd46e9e2820b797b899a07701c959b07b067e5eede960d39074c5e671d1a6846bdf97cb30b8d1fab95795e7ae7710e4f817bac9c
6
+ metadata.gz: 9522dbe0945c8951ab468c51309e206e260effdcaaac090d8925c4c18b28d1d5ebebe90e7e8575cbdee51665a0916c3f352846add52f3548c7651491a1623e85
7
+ data.tar.gz: ddb3e6688e11d140e0d87b13c6cb23ca2707d5e54868ecc18d1a09a38765aed3176cddc974662709234dbfbf13847b28fff3db45e66ddb9da35ca297e09a64d2
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2015 Mathías Montossi
1
+ Copyright 2016 Mathías Montossi
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/Rakefile CHANGED
@@ -17,8 +17,13 @@ end
17
17
 
18
18
 
19
19
 
20
+
21
+
20
22
  Bundler::GemHelper.install_tasks
21
23
 
24
+ APP_RAKEFILE = File.expand_path('../test/dummy/Rakefile', __FILE__)
25
+ load 'rails/tasks/engine.rake'
26
+
22
27
  require 'rake/testtask'
23
28
 
24
29
  Rake::TestTask.new(:test) do |t|
data/lib/slugs.rb CHANGED
@@ -1,8 +1,40 @@
1
- require 'slugs/active_record/base'
2
- require 'slugs/active_record/non_translatable'
3
- require 'slugs/active_record/translatable'
4
- require 'slugs/active_record/finders'
1
+ require 'slugs/extensions/action_dispatch/generator'
2
+ require 'slugs/extensions/action_dispatch/optimized_url_helper'
3
+ require 'slugs/extensions/active_record/base'
4
+ require 'slugs/concern'
5
+ require 'slugs/configuration'
5
6
  require 'slugs/railtie'
6
7
 
7
8
  module Slugs
9
+ class << self
10
+
11
+ def configuration
12
+ @configuration ||= Configuration.new
13
+ end
14
+
15
+ def configure
16
+ yield configuration
17
+ end
18
+
19
+ def parameterize(record, params)
20
+ if use_slug_for?(record, params)
21
+ if record.slug_changed?
22
+ record.slug_was
23
+ else
24
+ record.slug
25
+ end
26
+ else
27
+ record.to_param
28
+ end
29
+ end
30
+
31
+ def use_slug_for?(record, params)
32
+ if record.try(:sluggable?) && configuration.use_slug_proc
33
+ configuration.use_slug_proc.call record, params
34
+ else
35
+ false
36
+ end
37
+ end
38
+
39
+ end
8
40
  end
@@ -0,0 +1,50 @@
1
+ module Slugs
2
+ module Concern
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ before_create :set_slug
7
+ after_save :ensure_slug_uniqueness
8
+ validates_format_of :slug, with: /\A[a-z0-9\-]+\z/, allow_blank: true
9
+ validates_length_of :slug, maximum: 255, allow_blank: true
10
+ end
11
+
12
+ def sluggable?
13
+ self.class.sluggable?
14
+ end
15
+
16
+ private
17
+
18
+ def set_slug
19
+ options = self.class.slug
20
+ self.slug = slice(*options[:attributes]).values.join(' ').parameterize
21
+ end
22
+
23
+ def ensure_slug_uniqueness
24
+ options = self.class.slug
25
+ case options[:scope]
26
+ when Symbol
27
+ attribute = options[:scope]
28
+ scope = { attribute => send(attribute) }
29
+ when Array
30
+ attributes = options[:scope]
31
+ scope = attributes.map{ |a| [a, send(a)] }.to_h
32
+ end
33
+ if self.class.where(scope).where(slug: slug).where.not(id: id).any?
34
+ update_column :slug, "#{slug}-#{id}"
35
+ end
36
+ end
37
+
38
+ module ClassMethods
39
+
40
+ def slug
41
+ @slug ||= {}
42
+ end
43
+
44
+ def sluggable?
45
+ slug.present?
46
+ end
47
+
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,7 @@
1
+ module Slugs
2
+ class Configuration
3
+
4
+ attr_accessor :use_slug_proc
5
+
6
+ end
7
+ end
@@ -0,0 +1,24 @@
1
+ module Slugs
2
+ module Extensions
3
+ module ActionDispatch
4
+ module Generator
5
+
6
+ def generate
7
+ @set.formatter.generate(
8
+ named_route,
9
+ options,
10
+ recall,
11
+ lambda do |name, value|
12
+ if name == :controller
13
+ value
14
+ else
15
+ Slugs.parameterize value, options
16
+ end
17
+ end
18
+ )
19
+ end
20
+
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,20 @@
1
+ module Slugs
2
+ module Extensions
3
+ module ActionDispatch
4
+ module OptimizedUrlHelper
5
+
6
+ private
7
+
8
+ def parameterize_args(args)
9
+ parameterized_args = args.map do |arg|
10
+ Slugs.parameterize arg, @options
11
+ end
12
+ params = {}
13
+ @required_parts.zip(parameterized_args) { |k,v| params[k] = v }
14
+ params
15
+ end
16
+
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,19 @@
1
+ module Slugs
2
+ module Extensions
3
+ module ActiveRecord
4
+ module Base
5
+ extend ActiveSupport::Concern
6
+
7
+ module ClassMethods
8
+
9
+ def has_slug(*args)
10
+ include Slugs::Concern
11
+ options = args.extract_options!
12
+ @slug = options.merge(attributes: args)
13
+ end
14
+
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
data/lib/slugs/railtie.rb CHANGED
@@ -2,7 +2,15 @@ module Slugs
2
2
  class Railtie < Rails::Railtie
3
3
 
4
4
  initializer 'slugs' do
5
- ::ActiveRecord::Base.send :include, Slugs::ActiveRecord::Base
5
+ ::ActionDispatch::Routing::RouteSet::NamedRouteCollection::UrlHelper::OptimizedUrlHelper.prepend(
6
+ Slugs::Extensions::ActionDispatch::OptimizedUrlHelper
7
+ )
8
+ ::ActionDispatch::Routing::RouteSet::Generator.prepend(
9
+ Slugs::Extensions::ActionDispatch::Generator
10
+ )
11
+ ::ActiveRecord::Base.include(
12
+ Slugs::Extensions::ActiveRecord::Base
13
+ )
6
14
  end
7
15
 
8
16
  end
data/lib/slugs/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Slugs
2
2
 
3
- VERSION = '1.3.2'
3
+ VERSION = '2.0.0'
4
4
 
5
5
  end
data/test/dummy/Rakefile CHANGED
@@ -2,5 +2,4 @@
2
2
  # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
3
 
4
4
  require File.expand_path('../config/application', __FILE__)
5
-
6
- Dummy::Application.load_tasks
5
+ Rails.application.load_tasks
@@ -2,12 +2,12 @@
2
2
  // listed below.
3
3
  //
4
4
  // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
- // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
5
+ // or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
6
6
  //
7
7
  // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
8
  // compiled file.
9
9
  //
10
- // Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
10
+ // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
11
11
  // about supported directives.
12
12
  //
13
13
  //= require_tree .
@@ -3,11 +3,13 @@
3
3
  * listed below.
4
4
  *
5
5
  * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
- * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
6
+ * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
7
  *
8
- * You're free to add application-wide styles to this file and they'll appear at the top of the
9
- * compiled file, but it's generally better to create a new file per style scope.
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any styles
10
+ * defined in the other CSS/SCSS files in this directory. It is generally better to create a new
11
+ * file per style scope.
10
12
  *
11
- *= require_self
12
13
  *= require_tree .
14
+ *= require_self
13
15
  */
@@ -0,0 +1,7 @@
1
+ class Category < ActiveRecord::Base
2
+
3
+ belongs_to :shop
4
+
5
+ has_slug :name, scope: :shop_id
6
+
7
+ end
@@ -0,0 +1,8 @@
1
+ class Product < ActiveRecord::Base
2
+
3
+ belongs_to :shop
4
+ belongs_to :category
5
+
6
+ has_slug :name, scope: %i(shop_id category_id)
7
+
8
+ end
@@ -0,0 +1,5 @@
1
+ class Shop < ActiveRecord::Base
2
+
3
+ has_slug :name
4
+
5
+ end
@@ -0,0 +1,5 @@
1
+ class User < ActiveRecord::Base
2
+
3
+ has_slug :first_name, :last_name
4
+
5
+ end
@@ -1,14 +1,12 @@
1
1
  <!DOCTYPE html>
2
2
  <html>
3
- <head>
4
- <title>Dummy</title>
5
- <%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %>
6
- <%= javascript_include_tag "application", "data-turbolinks-track" => true %>
7
- <%= csrf_meta_tags %>
8
- </head>
9
- <body>
10
-
11
- <%= yield %>
12
-
13
- </body>
3
+ <head>
4
+ <title>Dummy</title>
5
+ <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
6
+ <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
7
+ <%= csrf_meta_tags %>
8
+ </head>
9
+ <body>
10
+ <%= yield %>
11
+ </body>
14
12
  </html>
File without changes
data/test/dummy/bin/rails CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
- APP_PATH = File.expand_path('../../config/application', __FILE__)
2
+ APP_PATH = File.expand_path('../../config/application', __FILE__)
3
3
  require_relative '../config/boot'
4
4
  require 'rails/commands'
data/test/dummy/bin/rake CHANGED
File without changes
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ require 'pathname'
3
+
4
+ # path to your application root.
5
+ APP_ROOT = Pathname.new File.expand_path('../../', __FILE__)
6
+
7
+ Dir.chdir APP_ROOT do
8
+ # This script is a starting point to setup your application.
9
+ # Add necessary setup steps to this file:
10
+
11
+ puts '== Installing dependencies =='
12
+ system 'gem install bundler --conservative'
13
+ system 'bundle check || bundle install'
14
+
15
+ # puts "\n== Copying sample files =="
16
+ # unless File.exist?('config/database.yml')
17
+ # system 'cp config/database.yml.sample config/database.yml'
18
+ # end
19
+
20
+ puts "\n== Preparing database =="
21
+ system 'bin/rake db:setup'
22
+
23
+ puts "\n== Removing old logs and tempfiles =="
24
+ system 'rm -f log/*'
25
+ system 'rm -rf tmp/cache'
26
+
27
+ puts "\n== Restarting application server =="
28
+ system 'touch tmp/restart.txt'
29
+ end
data/test/dummy/config.ru CHANGED
@@ -1,4 +1,4 @@
1
1
  # This file is used by Rack-based servers to start the application.
2
2
 
3
- require ::File.expand_path('../config/environment', __FILE__)
3
+ require ::File.expand_path('../config/environment', __FILE__)
4
4
  run Rails.application
@@ -4,7 +4,6 @@ require 'rails/all'
4
4
 
5
5
  Bundler.require(*Rails.groups)
6
6
  require 'slugs'
7
- require 'translatable_records'
8
7
 
9
8
  module Dummy
10
9
  class Application < Rails::Application
@@ -19,5 +18,8 @@ module Dummy
19
18
  # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
20
19
  # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
21
20
  # config.i18n.default_locale = :de
21
+
22
+ # Do not swallow errors in after_commit/after_rollback callbacks.
23
+ config.active_record.raise_in_transactional_callbacks = true
22
24
  end
23
25
  end
@@ -1,5 +1,5 @@
1
1
  # Set up gems listed in the Gemfile.
2
2
  ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../../../Gemfile', __FILE__)
3
3
 
4
- require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
4
+ require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
5
5
  $LOAD_PATH.unshift File.expand_path('../../../../lib', __FILE__)
@@ -1,25 +1,7 @@
1
- # SQLite version 3.x
2
- # gem install sqlite3
3
- #
4
- # Ensure the SQLite 3 gem is defined in your Gemfile
5
- # gem 'sqlite3'
6
1
  development:
7
- adapter: sqlite3
8
- database: db/development.sqlite3
9
- pool: 5
10
- timeout: 5000
2
+ adapter: postgresql
3
+ database: slugs_development
11
4
 
12
- # Warning: The database defined as "test" will be erased and
13
- # re-generated from your development database when you run "rake".
14
- # Do not set this db to the same as development or production.
15
5
  test:
16
- adapter: sqlite3
17
- database: ":memory:"
18
- pool: 5
19
- timeout: 5000
20
-
21
- production:
22
- adapter: sqlite3
23
- database: db/production.sqlite3
24
- pool: 5
25
- timeout: 5000
6
+ adapter: postgresql
7
+ database: slugs_test