Skip to content

Commit

Permalink
Merge pull request #196 from joshsoftware/issue_166
Browse files Browse the repository at this point in the history
Ref #166 Global config for slug builder
  • Loading branch information
dblock committed Mar 2, 2016
2 parents ff8157a + 19f708a commit 8e4849f
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 21 deletions.
2 changes: 1 addition & 1 deletion .rubocop_todo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Metrics/MethodLength:
# Offense count: 2
# Configuration parameters: CountComments.
Metrics/ModuleLength:
Max: 902
Max: 929

# Offense count: 3
Metrics/PerceivedComplexity:
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## 5.2.1 (Next)

* [#166](https://github.com/digitalplaywright/mongoid-slug/issues/166): Configure slug builder globally - [@anujaware](https://github.com/anujaware).
* Your contribution here.

## 5.2.0 (2016/01/03)
Expand Down
48 changes: 34 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,22 +86,42 @@ Custom Slug Generation
-------

By default Mongoid Slug generates slugs with stringex. If this is not desired you can
define your own slug generator like this:

```ruby
class Caption
include Mongoid::Document
include Mongoid::Slug

#create a block that takes the current object as an argument
#and returns the slug.
slug do |cur_object|
cur_object.slug_builder.to_url
end
end
```
define your own slug generator.

There are two ways to define slug generator.

### Global definition:

Configure a block in `config/initializers/mongoid_slug.rb` as follows:

```ruby
Mongoid::Slug.configure do |c|
#create a block that takes the current object as an argument
#and returns the slug.
c.slug = proc{|cur_obj|
cur_object.slug_builder.to_url
}
end
```

### Define it on model level:

```ruby
class Caption
include Mongoid::Document
include Mongoid::Slug
#create a block that takes the current object as an argument
#and returns the slug.
slug do |cur_object|
cur_object.slug_builder.to_url
end
end
```
You can call stringex `to_url` method.

You can define a slug builder globally and/or override it per model.

Scoping
-------

Expand Down
22 changes: 16 additions & 6 deletions lib/mongoid/slug.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,17 @@ module Slug
# alias_attribute :slugs, :_slugs
end

class << self
attr_accessor :default_slug
def configure(&block)
instance_eval(&block)
end

def slug(&block)
@default_slug = block if block_given?
end
end

module ClassMethods
# @overload slug(*fields)
# Sets one ore more fields as source of slug.
Expand Down Expand Up @@ -79,12 +90,7 @@ def slug(*fields, &block)
index(*Mongoid::Slug::Index.build_index(slug_scope_key, by_model_type))
end

#-- Why is it necessary to customize the slug builder?
default_url_builder = lambda do |cur_object|
cur_object.slug_builder.to_url
end

self.url_builder = block_given? ? block : default_url_builder
self.url_builder = block_given? ? block : default_slug_builder

#-- always create slug on create
#-- do not create new slug on update if the slug is permanent
Expand All @@ -108,6 +114,10 @@ def slug(*fields, &block)
end
end

def default_slug_builder
Mongoid::Slug.default_slug || ->(cur_object) { cur_object.slug_builder.to_url }
end

def look_like_slugs?(*args)
with_default_scope.look_like_slugs?(*args)
end
Expand Down
48 changes: 48 additions & 0 deletions spec/mongoid/slug_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,54 @@ module Mongoid
end
end

context 'when block is configured globally' do
before do
Mongoid::Slug.configure do |c|
c.slug do |cur_obj|
slug = cur_obj.slug_builder
("#{slug}-#{cur_obj.id}").to_url
end
end
end

after do
# Remove global configuration to avoid affect on
# other specs run after this spec
Mongoid::Slug.default_slug = nil
expect(Mongoid::Slug.default_slug).to be_nil
end

it 'generates a slug' do
expect(Mongoid::Slug.default_slug).to be_present
class Person
include Mongoid::Document
include Mongoid::Slug

field :name
slug :name
end

person = Person.create(name: 'John')
expect(person.to_param).to eql "john-#{person.id}"
end

it 'can be overridden at model level' do
expect(Mongoid::Slug.default_slug).to be_present
class Person
include Mongoid::Document
include Mongoid::Slug

field :name
slug :name do |cur_object|
cur_object.slug_builder.to_url
end
end

person = Person.create(name: 'John')
expect(person.to_param).to eql 'john'
end
end

context 'when slugged field contains non-ASCII characters' do
it 'slugs Cyrillic characters' do
book.title = 'Капитал'
Expand Down

0 comments on commit 8e4849f

Please sign in to comment.