Code Monkey home page Code Monkey logo

mongoid-slug's Introduction

Mongoid Slug

Mongoid Slug generates a URL slug or permalink based on one or more fields in a Mongoid model. It sits idly on top of stringex, supporting non-Latin characters.

Build Status Gem Version Code Climate

Version Support

Mongoid Slug 7.x requires at least Mongoid 7.0.0 and Ruby 2.7.0. For earlier Mongoid and Ruby version support, please use an earlier version of Mongoid Slug.

Mongoid Slug is compatible with all MongoDB versions which Mongoid supports, however, please see "Slug Max Length" section below for MongoDB 4.0 and earlier.

Installation

Add to your Gemfile:

gem 'mongoid-slug'

Usage

Set Up a Slug

class Book
  include Mongoid::Document
  include Mongoid::Slug

  field :title
  slug :title
end

Find a Document by its Slug

# GET /books/a-thousand-plateaus
book = Book.find params[:book_id]

Mongoid Slug will attempt to determine whether you want to find using the slugs field or the _id field by inspecting the supplied parameters.

  • Mongoid Slug will perform a find based on slugs only if all arguments passed to find are of the type String.
  • If your document uses BSON::ObjectId identifiers, and all arguments look like valid BSON::ObjectId, then Mongoid Slug will perform a find based on _id.
  • If your document uses any other type of identifiers, and all arguments passed to find are of the same type, then Mongoid Slug will perform a find based on _id.
  • If your document uses String identifiers and you want to be able find by slugs or ids, to get the correct behaviour, you should add a slug_id_strategy option to your _id field definition. This option should return something that responds to call (a callable) and takes one string argument, e.g. a lambda. This callable must return true if the string looks like one of your ids.
Book.fields['_id'].type
=> String

book = Book.find 'a-thousand-plateaus' # Finds by slugs
=> ...

class Post
  include Mongoid::Document
  include Mongoid::Slug

  field :_id, type: String, slug_id_strategy: lambda { |id| id.start_with?('...') }

  field :name
  slug  :name, history: true
end

Post.fields['_id'].type
=> String

post = Post.find 'a-thousand-plateaus' # Finds by slugs
=> ...

post = Post.find '50b1386a0482939864000001' # Finds by bson ids
=> ...

Examine slug.rb for all available options.

Updating Existing Records

To set slugs for existing records run following rake task:

rake mongoid_slug:set

You can pass model names as an option for which you want to set slugs:

rake mongoid_slug:set[Model1,Model2]

Nil Slugs

Empty slugs are possible and generate a nil value for the _slugs field. In the Post example above, a blank post name will cause the document record not to contain a _slugs field in the database. The default _slugs index is sparse, allowing that. If you wish to change this behavior add a custom validates_presence_of :_slugs validator to the document or change the database index to sparse: false.

Custom Slug Generation

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

There are two ways to define slug generator.

Globally

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

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

On Model

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

The to_url method comes from stringex.

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

Indexing

By default, Mongoid Slug will automatically generate an index for the slug, which will be created when you run rake db:create_indexes. This index will take into account scoping and other options described below.

To skip this index generation, you may set index: false as follows:

class Employee
  include Mongoid::Document
  include Mongoid::Slug

  field :name

  slug :name, index: :false
end

Scoping

To scope a slug by a reference association, pass :scope:

class Company
  include Mongoid::Document

  references_many :employees
end

class Employee
  include Mongoid::Document
  include Mongoid::Slug

  field :name
  referenced_in :company

  slug :name, scope: :company
end

In this example, if you create an employee without associating it with any company, the scope will fall back to the root employees collection.

Currently, if you have an irregular association name, you must specify the :inverse_of option on the other side of the assocation.

Embedded objects are automatically scoped by their parent.

Note that the unique index on the Employee collection in this example is derived from the scope value and is { _slugs: 1, company_id: 1}. Therefore :company must be referenced_in above the definition of slug or it will not be able to resolve the association and mistakenly create a { _slugs: 1, company: 1} index. An alternative is to scope to the field itself as follows:

class Employee
  include Mongoid::Document
  include Mongoid::Slug

  field :name
  field :company_id

  slug :name, scope: :company_id
end

You may scope slugs using multiple fields as per the following example:

class Employee
  include Mongoid::Document
  include Mongoid::Slug

  field :name
  field :company_id
  field :department_id

  # Scope slug uniqueness by a combination of company and department
  slug :name, scope: %i[company_id department_id]
end

Slug Max Length

MongoDB featureCompatibilityVersion "4.0" and earlier applies an Index Key Limit which limits the total size of an index entry to around 1KB and will raise error, 17280 - key too large to index when trying to create a record that causes an index key to exceed that limit. By default slugs are of the form text[-number] and the text portion is limited in size to Mongoid::Slug::MONGO_INDEX_KEY_LIMIT_BYTES - 32 bytes. You can change this limit with max_length or set it to nil if you're running MongoDB with failIndexKeyTooLong set to false.

class Company
  include Mongoid::Document
  include Mongoid::Slug

  field :name

  slug  :name, max_length: 24
end

Optionally Find and Create Slugs per Model Type

By default when using STI, the scope will be around the super-class.

class Book
  include Mongoid::Document
  include Mongoid::Slug
  field :title

  slug  :title, history: true
  embeds_many :subjects
  has_many :authors
end

class ComicBook < Book
end

book = Book.create(title: 'Anti Oedipus')
comic_book = ComicBook.create(title: 'Anti Oedipus')
comic_book.slugs.should_not eql(book.slugs)

If you want the scope to be around the subclass, then set the option by_model_type: true.

class Book
  include Mongoid::Document
  include Mongoid::Slug
  field :title

  slug  :title, history: true, by_model_type: true
  embeds_many :subjects
  has_many :authors
end

class ComicBook < Book
end

book = Book.create(title: 'Anti Oedipus')
comic_book = ComicBook.create(title: 'Anti Oedipus')
comic_book.slugs.should eql(book.slugs)

History

Enable slug history tracking by setting history: true.

class Page
  include Mongoid::Document
  include Mongoid::Slug

  field :title

  slug :title, history: true
end

The document will then be returned for any of the saved slugs:

page = Page.new title: "Home"
page.save
page.update_attributes title: "Welcome"

Page.find("welcome") == Page.find("home") # => true

Reserved Slugs

Pass words you do not want to be slugged using the reserve option:

class Friend
  include Mongoid::Document

  field :name
  slug :name, reserve: ['admin', 'root']
end

friend = Friend.create name: 'admin'
Friend.find('admin') # => nil
friend.slug # => 'admin-1'

When reserved words are not specified, the words 'new' and 'edit' are considered reserved by default. Specifying an array of custom reserved words will overwrite these defaults.

Localize Slugs

The slugs can be localized. This feature is built upon Mongoid localized fields, so fallbacks and localization works as documented in the Mongoid manual.

class PageSlugLocalize
  include Mongoid::Document
  include Mongoid::Slug

  field :title, localize: true
  slug  :title, localize: true
end

By specifying localize: true, the slug index will be created on the I18n.default_locale field only. For example, if I18n.default_locale is :en, the index will be generated as follows:

slug :title, localize: true

# The following index is auto-generated:
index({ '_slugs.en' => 1 }, { unique: true, sparse: true })

If you are supporting multiple locales, you may specify the list of locales on which to create indexes as an Array.

slug :title, localize: [:fr, :es, :de]

# The following indexes are auto-generated:
index({ '_slugs.fr' => 1 }, { unique: true, sparse: true })
index({ '_slugs.es' => 1 }, { unique: true, sparse: true })
index({ '_slugs.de' => 1 }, { unique: true, sparse: true })

Custom Find Strategies

By default find will search for the document by the id field if the provided id looks like a BSON::ObjectId, and it will otherwise find by the _slugs field. However, custom strategies can ovveride the default behavior, like e.g:

module Mongoid::Slug::UuidIdStrategy
  def self.call id
    id =~ /\A([0-9a-fA-F]){8}-(([0-9a-fA-F]){4}-){3}([0-9a-fA-F]){12}\z/
  end
end

Use a custom strategy by adding the slug_id_strategy annotation to the _id field:

class Entity
  include Mongoid::Document
  include Mongoid::Slug

  field :_id, type: String, slug_id_strategy: UuidIdStrategy

  field :user_edited_variation
  slug  :user_edited_variation, history: true
end

Adhoc Checking Whether a Slug is Unique

Lets say you want to have a auto-suggest function on your GUI that could provide a preview of what the url or slug could be before the form to create the record was submitted.

You can use the UniqueSlug class in your server side code to do this, e.g.

title = params[:title]
unique = Mongoid::Slug::UniqueSlug.new(Book.new).find_unique(title)
...
# return some representation of unique

Contributing

Mongoid-slug is work of many of contributors. You're encouraged to submit pull requests, propose features, ask questions and discuss issues. See CONTRIBUTING for details.

Copyright & License

Copyright (c) 2010-2017 Hakan Ensari & Contributors, see LICENSE for details.

mongoid-slug's People

Contributors

ajsharp avatar al avatar anujaware avatar astjohn avatar bdmac avatar ches avatar da-z avatar dblock avatar digitalplaywright avatar dmathieu avatar douwem avatar empact avatar etehtsea avatar fudoshiki avatar guyboertje avatar hakanensari avatar johnnyshields avatar kailan avatar klacointe avatar loopj avatar lucasrenan avatar mzikherman avatar sagmor avatar simi avatar siong1987 avatar tiendung avatar trevor avatar xslim avatar zefer avatar zeke avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mongoid-slug's Issues

m::s takes over url creation (and I don't apreciate that)

Hello,

I got slug to work nicely with my models, but I am having a bit of a problem, with the way, that all routes now are slugged instead of using the document id.

I other words, even though my model has a slug, I would want all routes except a very few ones to work as they did before, i.e. edit_record_path(record) should not become "/record/slug/edit", but "/record/my-old-mongodbid", except for the recordcontroller#show method (public facing), where I would want to use the slug. Otherwise I would have to make huge changes all over my app and I am a bit too lazy for that. I am using inherited_ressources, which wants an id and not a slug.

Document how to generate slugs for existing documents

I had a hard time working out how add a slug retrospectively. Given the model:

class Product
  include Mongoid::Document
  include Mongoid::Slug

  field :name
  field :slug

  slug :name
end

I initially tried calling save but this doesn't generate it.
The only way I could find to create slugs for existing documents was:

Product.all.each do |product|
  product.send(:generate_slug!)
  product.save
end

This seems a bit hacky... Is there a better way to do this?

If so could you add it to the README?
If this is the only way, could you expose a public method to generating slugs on existing documents?

Global slugs

I'd like to be able to use slugs in a global scope and have all entities be available at the root level.

For example

class User
  field :name
  slug :name
end

class Topic
  field :subject
  slug :subject
end

User.create(name: "Johnny").to_param == "johnny"
Topic.create(subject: "Johnny").to_param == "johnny-1"

I'm curious if this is something you think should be in this gem and would do, or be interested in a pull request for?

slug name

there used to be a way of customizing the slug name

class MyModel
  include Mongoid::Document
  include Mongoid::Slug

  field :bam
  slug :bam, :as => :ham
end

What's the best way to achieve this now?

Upgrading docs

Hello,

in the upgrading to 1.0.0. document, it could be a good idea to refer to the possibility to use dynamic fields. Instead of editing your models directly, you could just use
my_model[:_slugs] = array_of_old_slugs

I used this code

def copy_slug(e)
  slugs = []
  if e[:slug_history] != nil
    e[:slug_history].each do |h|
      slugs << h unless (h == nil || h == "")
    end
  end
  slugs << e[:slug]
  e[:_slugs] = slugs
  e.save
  p " - #{e[:_slugs]}"
end

It should be noted that the order has relevance and the default slug will be the tail.

Another thing: I have embedded documents with slugs. Upon running

rake db:mongoid:create_indexes

I get errors like this

MONGOID: Index: {:_slugs=>1}, Options: {:unique=>true}
MONGOID: Created indexes on Portfolio:
MONGOID: Index: {:_slugs=>1}, Options: {:unique=>true}
MONGOID: Index ignored on: PortfolioItem, please define in the root model.

PortfolioItem is embedded in Portfolio, so the index should be created there. How am I supposed to make Slug aware of this?

slug for fields that are localized

so far the only well working solutions is to make slug permanent and set value by passing block, i.e.:

  field :name, :type => String, :localize => true
  slug :name, :permanent => true do |category|
    category.name
  end

in future would be nice if slug would be also localize, it's require to think about few cases like:

  • overwriting find_by_slug ( so it could find object by any translated slug )
  • fetching value for slug (it's stored as hash in db)

Can't catch Mongoid not found exceptions in controllers

In my controller code I'm catching not found exceptions so I can raise the appropriate message to the user. When using the find_by_slug method (where(slug_name => slug).first rescue nil) you are catching all exceptions. This means it's no longer possible to catch not found exceptions raised by mongoid in the normal way. May I suggest either not catching any exceptions or only catching specific exceptions so that the usual exceptions are not caught by the gem. IMHO using mongoid-slug should not change the default behaviour of mongoid's query methods.

Store slug or slugs in an array

Storing slugs in an array simplifies the code significantly, reducing code smell and doing away with the need to have a separate history field, among other things.

I've done some work on this, but left it at the point where I'd attempt to handle the transition/migration for documents slugged the former way. Patches are more than welcome, as I don't think I'll get a chance to work on this in the near future.

Another alternative, of course, would be to stop worrying about backwards-compatibility and roll out the new logic as is.

I'll leave it to the existing users of this library to figure this one out.

Problem with non english languages

For example if slug filed is all in Greek you get an empty string

It can be easily fixed with a small change:

slug = ("#{slug_base} #{suffix}").to_url

and require the stringex gem

works great with chinese and arabian also ;)

`eval': incompatible encoding regexp match (UTF-8 regexp with ASCII-8BIT string)

Doesn't work for "Paul C\xE9zanne" (Paul Cรฉzanne). Workaround would be ok.

    Main.rb:140:in `eval': incompatible encoding regexp match (UTF-8 regexp with ASCII-8BIT string) (Encoding::CompatibilityError)
    from C:/Ruby/lib/ruby/gems/1.9.1/gems/stringex-1.2.0/lib/lucky_sneaks/string_extensions.rb:143:in `block in convert_misc_characters'
    from C:/Ruby/lib/ruby/gems/1.9.1/gems/stringex-1.2.0/lib/lucky_sneaks/string_extensions.rb:141:in `each'
    from C:/Ruby/lib/ruby/gems/1.9.1/gems/stringex-1.2.0/lib/lucky_sneaks/string_extensions.rb:141:in `convert_misc_characters'
    from C:/Ruby/lib/ruby/gems/1.9.1/gems/stringex-1.2.0/lib/lucky_sneaks/string_extensions.rb:45:in `remove_formatting'
    from C:/Ruby/lib/ruby/gems/1.9.1/gems/stringex-1.2.0/lib/lucky_sneaks/string_extensions.rb:39:in `to_url'
    from C:/Ruby/lib/ruby/gems/1.9.1/gems/mongoid_slug-0.6.2/lib/mongoid/slug.rb:80:in `build_slug'
    from C:/Ruby/lib/ruby/gems/1.9.1/gems/mongoid_slug-0.6.2/lib/mongoid/slug.rb:84:in `find_unique_slug'
    from C:/Ruby/lib/ruby/gems/1.9.1/gems/mongoid_slug-0.6.2/lib/mongoid/slug.rb:94:in `generate_slug!'
    from C:/Ruby/lib/ruby/gems/1.9.1/gems/mongoid_slug-0.6.2/lib/mongoid/slug.rb:98:in `generate_slug'
    from C:/Ruby/lib/ruby/gems/1.9.1/gems/activesupport-3.0.3/lib/active_support/callbacks.rb:419:in `_run_save_callbacks'

custom slug builder doesn't allow for ids

i use a custom slug, because what i want is try one field and if it doesn't exist to resort to the id. so it looks like this:

slug :index => true, :history => true do |doc|
  [doc.some_field, doc._id.to_s].reject(&:blank?).first.to_url
end

but in the case where some_field is blank i'm not getting the id as the slug because of this:

#do not allow a slug that can be interpreted as the current document id
existing_slugs << _slug unless self.class.look_like_slugs?([_slug])

Why can't we have a slug that looks like the document id?

Doesn't work with Mongoid::Paranoia

Not sure if this is in scope, or even how to go about fixing it. But #find_unique_slug doesn't find paranoid deleted objects, and therefor is capable of generating duplicate slugs.

Refactor in 0.9.0 to 0.10.0 breaks slug_changed?

I've been trying to figure out a deeper issue, but this is one I've come across in the meantime that's pretty obviously wrong to me. Not suggesting this is necessarily a good test case, but it demonstrates the problem. This example passes in v0.9.0, but fails in v0.10.0

describe "refactor issue" do
  before do
    Book.create(:title => "A Thousand Plateaus")
  end

  it "handles slug_changed? correctly" do
    book = Book.first
    book.slug_changed?.should be_false
    book.slug = "Something Else"
    book.slug_changed?.should be_true
  end
end

Gives output:

$ rspec -e 'refactor issue handles slug_changed? correctly'
Run options: include {:full_description=>/(?-mix:refactor\ issue\ handles\ slug_changed\?\ correctly)/}
F

Failures:

  1) refactor issue handles slug_changed? correctly
     Failure/Error: book.slug_changed?.should be_true
       expected false to be true
     # ./spec/mongoid/test_spec.rb:10:in `block (2 levels) in <top (required)>'

Finished in 0.01319 seconds
1 example, 1 failure

Failed examples:

rspec ./spec/mongoid/test_spec.rb:6 # refactor issue handles slug_changed? correctly

The problem that I'm seeing is that Mongoid::Dirty#attribute_changed? really expects a string, not a symbol. So when #slug_changed? in the case of the Book test class ends up calling attribute_changed?(:slug) rather than attribute_changed?('slug'), the return value is always going to be false.

So if I change line 324 of slug.rb to attribute_changed? slug_name.to_s, another test fails, and it's not obvious to me how to resolve that one.

  1) Mongoid::Slug when the slugged field is set manually when it is set to an empty string generate a new one
     Failure/Error: book.to_param.should eql "a-thousand-plateaus"

       expected: "a-thousand-plateaus"
            got: ""

       (compared using eql?)
     # ./spec/mongoid/slug_spec.rb:547:in `block (4 levels) in <module:Mongoid>'

Will take a fresh look tomorrow, but maybe this is an obvious fix for someone who's a little more familiar with the code base.

Why new gem :require style?

I'm curious, why did you make this change in 0.4.7?

gem 'mongoid_slug', :require => 'mongoid/slug'

In 0.4.6 it was:

gem 'mongoid_slug'

Is this the recommended practice for mongoid plugins?

Anyhow, since this breaks backwards compatibility, I would argue that it warranted a point version change (0.5).

mongoid_slug dependency on mongoid is too strict

mongoid_slug won't bundle with Mongoid 3.1:

Bundler could not find compatible versions for gem "mongoid":
  In Gemfile:
    mongoid_slug (>= 0) ruby depends on
      mongoid (~> 3.0.0) ruby

    mongoid (3.1.0)

should depend on mongoid (~> 3.0)

understanding spec

I am working on getting the specs to pass on my Mongoid 3.0 branch. There is a spec I do not understand. This spec:
https://github.com/hakanensari/mongoid-slug/blame/master/spec/models/animal.rb

Has a key on two fields:
key :name, :nickname

I can not find this feature in the Mongod 2.x manual and also not in the replacement custom id feature in Mongoid 3.0:
http://mongoid.org/en/mongoid/docs/documents.html

@astjohn @hakanensari , please let me know if you have an explanation of what the intended semantics is of this key on two fields.

slug block doesn't receive the document

Hi,
I'm trying to build a slug based on associations. I'm stuck because the slug method doesn't receive the document, but the value of listed fields.

slug :name do |book|
    "#{book.name}-#{book.authors.map{|a| a.name.parametrize}.join('-')}"
end 

On the above example, book should be the instance of document, but it is the value of :name attribute.

slug from an embedded doc

If i have the following example:

class Story
include Mongoid::Document

embeds_one :info

end

class Info
include Mongoid::Document

field :title
embedded_in :story

end

How can use the Info.title as the slug on the Story class? Is that possible?

Shouldn't convert fractions to slashes

I have a project which converted "ยฝ" into "1/2", which, because I'm using slugs in the URL, doesn't work. Just a heads up that you might want to remove all slashes from the final generated slug.

Slugs not generated with rails when created with update_attributes (nested)

Excuse the title, slightly confusing.

If I have a model Property (which has slugs) embedded in a model Type and I create properties using rails nested model forms (as in @type.update_attributes(params_including_property_params) the slug field in Property is empty.

I assume the required callback isn't being called by update_attributes?

I'm guessing I can create my own callback but it would be nice to eliminate this gotcha

What's the best way around this?

Incompatibility with Mongoid 3.0.0.rc

Gemfile:

gem "mongoid", "~> 3.0.0.rc"
gem 'mongoid_slug'

Error after bundle command:

Bundler could not find compatible versions for gem "mongoid":
In Gemfile:
mongoid_slug (>= 0) ruby depends on
mongoid (~> 2.0.0.beta7) ruby
mongoid (3.0.0.rc)

Publishing gem on RubyGems

Hi,
is it possible to publish this great gem?
I am using it in my engines and since the gem is available only via github it's not possible to use it as dependency.

Thanks Tom

just following instructions will not work

Here is description of problem:
https://groups.google.com/forum/#!topic/mongoid/YO8_zrP1GAc

The gist idea is that just including Mongoid::Slugs and slug :some_field is not enough. Just with these setup rails will complain in link_to method (Route not found, and :id => whole object). To solve this problem, as it was pointed in group discussion we must generate slugs.
However, generating them we use PRIVATE method generate_slug!.

One solution is to move generate_slug! out of private scope and give instructions in README to generate slugs.

Is it possible to set perma link just as is?

I see that all the non-alphabets are converted to alphabet characters. Is there anyway that I can change the setting to save to slug just as it is? without converting it to the alphabets?

Untitled

Hi,

Is it possible to generate a slug from a Hash field ?

Something like this:

class Obj
  include Mongoid::Document
  include Mongoid::Slug

  field :name
  field :address, :type => Hash
  
  slug :name, address[:city], :as => :permalink

end

Thanks a lot,

What to do if title is editable?

Hi,

I'm wondering if mongoid-slug can be used in a situation where the slugged field is editable.

I thought of using :id and :title, but Mongoid id is really very long. How would I split it into a smaller hash before combining it into a named slug?

Order_by bug.

lib/mongoid/slug.rb, line 125 is:
order_by([slug_name, :desc]).first.try(:read_attribute, slug_name)
This can lead to error because of :sort=>[[:position, :asc], :slug, :desc]
It should be:
order_by(slug_name.desc).first.try(:read_attribute, slug_name)

scoped slug causes Mongoid::Errors::InvalidCollection error

Using:

gem "mongo",         "= 1.4.0"
gem "mongoid",       "= 2.2"
gem "mongoid_slug",  "~> 0.10.0"

Code to reproduce:

class Dashboard
  include Mongoid::Document
  include Mongoid::Slug

  slug :friendly_id

  field :friendly_id, :default => Time.now.strftime('%m%d')

  embeds_many :tabs, :class_name => "BasicTab"
end

class BasicTab
  include Mongoid::Document
  include Mongoid::Slug

  field :friendly_id, :default => 'tab' + Time.now.strftime('%m%d')

  slug :friendly_id, :scope => :dashboard

  embedded_in :dashboard
end

No problem if the dashboard object is a new record:

ree-1.8.7-2011.03 :063 > d = Dashboard.new
 => #<Dashboard _id: 4f7f374be628f81068000013, slug: nil, created_at: nil, updated_at: nil, _type: nil, friendly_id: "0406"> 
ree-1.8.7-2011.03 :064 > d.tabs << BasicTab.new
 => [#<BasicTab _id: 4f7f3752e628f81068000014, slug: nil, created_at: nil, updated_at: nil, _type: nil, friendly_id: "tab0406">]

Fails otherwise:

ree-1.8.7-2011.03 :065 > d.save       
 => true 
ree-1.8.7-2011.03 :066 > d.reload
 => #<Dashboard _id: 4f7f374be628f81068000013, slug: "0406-1", created_at: Fri Apr 06 18:36:13 UTC 2012, updated_at: Fri Apr 06 18:36:13 UTC 2012, _type: nil, friendly_id: "0406"> 
ree-1.8.7-2011.03 :067 > d.tabs << BasicTab.new
Mongoid::Errors::InvalidCollection: Access to the collection for BasicTab is not allowed since it is an embedded document, please access a collection from the root document.
    from /var/bundler/turtle/ruby/1.8/gems/mongoid-2.2.0/lib/mongoid/collections.rb:55:in `collection'
    from /var/bundler/turtle/ruby/1.8/gems/mongoid-2.2.0/lib/mongoid/contexts/mongo.rb:146:in `execute'
    from /var/bundler/turtle/ruby/1.8/gems/mongoid-2.2.0/lib/mongoid/contexts/mongo.rb:207:in `iterate'
    from /var/bundler/turtle/ruby/1.8/gems/mongoid-2.2.0/lib/mongoid/criteria.rb:144:in `each'
    from /var/bundler/turtle/ruby/1.8/gems/mongoid-2.2.0/lib/mongoid/criteria.rb:144:in `tap'
    from /var/bundler/turtle/ruby/1.8/gems/mongoid-2.2.0/lib/mongoid/criteria.rb:144:in `each'
    from /var/bundler/turtle/ruby/1.8/gems/mongoid_slug-0.10.0/lib/mongoid/slug.rb:177:in `map'
    from /var/bundler/turtle/ruby/1.8/gems/mongoid_slug-0.10.0/lib/mongoid/slug.rb:177:in `find_unique_slug_for'
    from /var/bundler/turtle/ruby/1.8/gems/mongoid_slug-0.10.0/lib/mongoid/slug.rb:306:in `find_unique_slug_for'
    from /var/bundler/turtle/ruby/1.8/gems/mongoid_slug-0.10.0/lib/mongoid/slug.rb:346:in `find_unique_slug'
    from /var/bundler/turtle/ruby/1.8/gems/mongoid_slug-0.10.0/lib/mongoid/slug.rb:286:in `build_slug'
    from /var/bundler/turtle/ruby/1.8/gems/mongoid_slug-0.10.0/lib/mongoid/slug.rb:87:in `_callback_before_9053'
    from /var/bundler/turtle/ruby/1.8/gems/activesupport-3.0.7/lib/active_support/callbacks.rb:422:in `_run_save_callbacks'
    from /var/bundler/turtle/ruby/1.8/gems/activesupport-3.0.7/lib/active_support/callbacks.rb:94:in `send'
    from /var/bundler/turtle/ruby/1.8/gems/activesupport-3.0.7/lib/active_support/callbacks.rb:94:in `run_callbacks'
    from /var/bundler/turtle/ruby/1.8/gems/mongoid-2.2.0/lib/mongoid/persistence/insertion.rb:24:in `prepare'
    from /var/bundler/turtle/ruby/1.8/gems/mongoid-2.2.0/lib/mongoid/persistence/insertion.rb:22:in `tap'
    from /var/bundler/turtle/ruby/1.8/gems/mongoid-2.2.0/lib/mongoid/persistence/insertion.rb:22:in `prepare'
    from /var/bundler/turtle/ruby/1.8/gems/mongoid-2.2.0/lib/mongoid/persistence/operations/embedded/insert.rb:30:in `persist'
    from /var/bundler/turtle/ruby/1.8/gems/mongoid-2.2.0/lib/mongoid/persistence.rb:44:in `insert'
    from /var/bundler/turtle/ruby/1.8/gems/mongoid-2.2.0/lib/mongoid/persistence.rb:149:in `save'
    from /var/bundler/turtle/ruby/1.8/gems/mongoid-2.2.0/lib/mongoid/relations/embedded/many.rb:29:in `<<'
    from /var/bundler/turtle/ruby/1.8/gems/mongoid-2.2.0/lib/mongoid/relations/embedded/many.rb:26:in `each'
    from /var/bundler/turtle/ruby/1.8/gems/mongoid-2.2.0/lib/mongoid/relations/embedded/many.rb:26:in `<<'
    from /var/bundler/turtle/ruby/1.8/gems/mongoid-2.2.0/lib/mongoid/relations/embedded/atomic.rb:61:in `call'
    from /var/bundler/turtle/ruby/1.8/gems/mongoid-2.2.0/lib/mongoid/relations/embedded/atomic.rb:61:in `atomically'
    from /var/bundler/turtle/ruby/1.8/gems/mongoid-2.2.0/lib/mongoid/relations/embedded/atomic.rb:82:in `call'
    from /var/bundler/turtle/ruby/1.8/gems/mongoid-2.2.0/lib/mongoid/relations/embedded/atomic.rb:82:in `count_executions'
    from /var/bundler/turtle/ruby/1.8/gems/mongoid-2.2.0/lib/mongoid/relations/embedded/atomic.rb:60:in `atomically'
    from /var/bundler/turtle/ruby/1.8/gems/mongoid-2.2.0/lib/mongoid/relations/embedded/many.rb:25:in `<<'
    from (irb):67

use slug in differents controllers

I have this mode:

class Board
 include Mongoid::Document
 include Mongoid::Timestamps::Created
 include Mongoid::Slug

 field :name

 #slug
 slug :name

end

I have a controller in root controllers directory with name boards_controller.rb

But I have inside controller directory a directory with name admin and I have inside other boards_controller.rb.

Then for this last controller have a path controllers/admin/boards_controller.rb

I want to use slug only in first controller. In this last controller I don't want to use slug.
How can I do it?

The question is in http://stackoverflow.com/questions/9624623/scoping-mongoid-slug

Thank you

specs, let vs let!, and Mongoid::Errors::Callback

I'm in the process of upgrading to 3.x and ran into a weird issue in my controller specs.

describe DiseasesController do
  let(:disease) {Fabricate(:disease)}

  it "assigns the disease as @disease" do
    put :update, id: disease.id.to_s, disease: {}
    assigns(:disease).should eq(disease)
  end

etc...

The above, which used to work fine, now produces Mongoid::Errors::Callback. This is the case when using Fabricator or FactoryGirl. The model does not have callbacks and I even tried commenting all validations, callbacks, fields, etc... Changing the let to let! fixes the issue. I'm not sure why this is occurring and any help is appreciated.

recreating all slugs

I found myself having to recreate all slugs during development. In order to this I needed to override the method on the model:

  def slug_should_be_rebuilt?
    #force slug creation
    true
  end

would there be another way to do this?

ability to use several slugs in a model ?

Feature suggestion:

i need to use i18n slugs in order to get url translated in several languages.

i first thought the gem could do it using :as option like this :

slug :title_fr, :as => :slug_fr
slug :title_en, :as => :slug_en

but it doesn't seem to really work and I don't see any of your example using the slug method twice

I don't see implications at code level now but it could be very insteresting and probably simple rather than creating a new plugin.

maybe i'll try to fork the project (but i've never done that before)

Making custom slugs

I'm trying to create a custom slug using the instructions in the slug.rb. Here is my attempt:

 slug :title do |doc|
   doc._id[0..5]+"/"+doc.title.sub(/\s+/,'-')
 end

But this doesn't seem to be working. Not even debugger is stopping the flow inside the block that is passed to it. Can you shed some light on what needs to be done here, and what I'm doing wrong. Thanks.

NoMethodError: undefined method `slug' error

Slug seems to be undefined for a model attribute that has been slugged.

>> Member.last.slug
NoMethodError: undefined method `slug' for #<Member:0x007ffd4499eff0>
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/gems/mongoid-3.0.5/lib/mongoid/attributes.rb:225:in `method_missing'
    from (irb):22
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/gems/railties-3.2.2/lib/rails/commands/console.rb:47:in `start'
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/gems/railties-3.2.2/lib/rails/commands/console.rb:8:in `start'
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/gems/railties-3.2.2/lib/rails/commands.rb:41:in `<top (required)>'
    from script/rails:6:in `require'
    from script/rails:6:in `<main>'

Also, I get this error when trying to set the username, which is slugged.

>> m = Member.last
>> m.username = "badninja"
>> m.save
NoMethodError: undefined method `username' for "badninja":String
    from /Users/andy/workspace/myapp/app/models/member.rb:51:in `block in <class:Member>'
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/bundler/gems/mongoid-slug-0294c663c42b/lib/mongoid/slug.rb:111:in `call'
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/bundler/gems/mongoid-slug-0294c663c42b/lib/mongoid/slug.rb:111:in `find_unique_slug_for'
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/bundler/gems/mongoid-slug-0294c663c42b/lib/mongoid/slug.rb:272:in `find_unique_slug_for'
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/bundler/gems/mongoid-slug-0294c663c42b/lib/mongoid/slug.rb:303:in `find_unique_slug'
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/bundler/gems/mongoid-slug-0294c663c42b/lib/mongoid/slug.rb:256:in `build_slug'
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/gems/activesupport-3.2.2/lib/active_support/callbacks.rb:407:in `_run__1994561856913203917__save__2219248855043090796__callbacks'
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/gems/activesupport-3.2.2/lib/active_support/callbacks.rb:405:in `__run_callback'
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/gems/activesupport-3.2.2/lib/active_support/callbacks.rb:385:in `_run_save_callbacks'
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/gems/activesupport-3.2.2/lib/active_support/callbacks.rb:81:in `run_callbacks'
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/gems/mongoid-3.0.5/lib/mongoid/callbacks.rb:100:in `run_callbacks'
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/gems/mongoid-3.0.5/lib/mongoid/persistence/modification.rb:23:in `prepare'
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/gems/mongoid-3.0.5/lib/mongoid/persistence/operations/update.rb:43:in `persist'
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/gems/mongoid-3.0.5/lib/mongoid/persistence.rb:139:in `update'
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/gems/mongoid-3.0.5/lib/mongoid/persistence.rb:81:in `save'
    from (irb):25
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/gems/railties-3.2.2/lib/rails/commands/console.rb:47:in `start'
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/gems/railties-3.2.2/lib/rails/commands/console.rb:8:in `start'
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/gems/railties-3.2.2/lib/rails/commands.rb:41:in `<top (required)>'
    from script/rails:6:in `require'

This is the model:

class Member 
  include Mongoid::Document
  include Mongoid::Slug

  field :username, type: String
  slug :username
end

This is my gemlock:

GIT
  remote: git://github.com/calicoder/active_shipping
  revision: b82cfac222e478c3a90647e0203f9677359ef2f7
  specs:
    active_shipping (0.9.14)
      active_utils (>= 1.0.1)
      activesupport (>= 2.3.5)
      builder
      i18n
      json (>= 1.5.1)

GIT
  remote: git://github.com/digitalplaywright/mongoid-slug.git
  revision: 0294c663c42bb7581578b0cbb99d145b82adf472
  specs:
    mongoid_slug (0.20.0)
      mongoid (~> 3.0.0)
      stringex (~> 1.4)

GIT
  remote: git://github.com/thoughtbot/paperclip.git
  revision: 4bea897fa277eb3928442826e1098108590d9b0b
  specs:
    paperclip (3.1.4)
      activemodel (>= 3.0.0)
      activerecord (>= 3.0.0)
      activesupport (>= 3.0.0)
      cocaine (>= 0.0.2)
      mime-types

GIT
  remote: https://github.com/37signals/mail_view.git
  revision: 86a56c55143b3688add21ac95946c008df32c491
  specs:
    mail_view (1.0.1)
      tilt

GEM
  remote: https://rubygems.org/
  specs:
    actionmailer (3.2.2)
      actionpack (= 3.2.2)
      mail (~> 2.4.0)
    actionpack (3.2.2)
      activemodel (= 3.2.2)
      activesupport (= 3.2.2)
      builder (~> 3.0.0)
      erubis (~> 2.7.0)
      journey (~> 1.0.1)
      rack (~> 1.4.0)
      rack-cache (~> 1.1)
      rack-test (~> 0.6.1)
      sprockets (~> 2.1.2)
    active_utils (1.0.4)
      activesupport (>= 2.3.11)
      i18n
    activemodel (3.2.2)
      activesupport (= 3.2.2)
      builder (~> 3.0.0)
    activerecord (3.2.2)
      activemodel (= 3.2.2)
      activesupport (= 3.2.2)
      arel (~> 3.0.2)
      tzinfo (~> 0.3.29)
    activeresource (3.2.2)
      activemodel (= 3.2.2)
      activesupport (= 3.2.2)
    activesupport (3.2.2)
      i18n (~> 0.6)
      multi_json (~> 1.0)
    addressable (2.3.2)
    arel (3.0.2)
    asset_sync (0.5.0)
      activemodel
      fog
    awesome_print (1.0.2)
    aws-s3 (0.6.3)
      builder
      mime-types
      xml-simple
    aws-sdk (1.3.9)
      httparty (~> 0.7)
      json (~> 1.4)
      nokogiri (>= 1.4.4)
      uuidtools (~> 2.1)
    bcrypt-ruby (3.0.1)
    blankslate (2.1.2.4)
    bson (1.7.0)
    bson_ext (1.7.0)
      bson (~> 1.7.0)
    builder (3.0.0)
    cancan (1.6.8)
    capybara (1.1.2)
      mime-types (>= 1.16)
      nokogiri (>= 1.3.3)
      rack (>= 1.0.0)
      rack-test (>= 0.5.4)
      selenium-webdriver (~> 2.0)
      xpath (~> 0.1.4)
    childprocess (0.3.5)
      ffi (~> 1.0, >= 1.0.6)
    chunky_png (1.2.6)
    cocaine (0.3.0)
    coffee-rails (3.2.2)
      coffee-script (>= 2.2.0)
      railties (~> 3.2.0)
    coffee-script (2.2.0)
      coffee-script-source
      execjs
    coffee-script-source (1.3.3)
    compass (0.12.2)
      chunky_png (~> 1.2)
      fssm (>= 0.2.7)
      sass (~> 3.1)
    compass-rails (1.0.3)
      compass (>= 0.12.2, < 0.14)
    crack (0.3.1)
    css_parser (1.2.6)
      addressable
      rdoc
    dalli (2.1.0)
    database_cleaner (0.8.0)
    delayed_job (3.0.3)
      activesupport (~> 3.0)
    delayed_job_mongoid (2.0.0)
      delayed_job (~> 3.0)
      mongoid (~> 3.0)
    devise (2.1.2)
      bcrypt-ruby (~> 3.0)
      orm_adapter (~> 0.1)
      railties (~> 3.1)
      warden (~> 1.2.1)
    devise-encryptable (0.1.1)
      devise (>= 2.1.0.rc)
    diff-lcs (1.1.3)
    ejs (1.0.0)
    erubis (2.7.0)
    exception_notification (2.6.1)
      actionmailer (>= 3.0.4)
    excon (0.16.2)
    execjs (1.4.0)
      multi_json (~> 1.0)
    factory_girl (4.0.0)
      activesupport (>= 3.0.0)
    factory_girl_rails (4.0.0)
      factory_girl (~> 4.0.0)
      railties (>= 3.0.0)
    faker (1.0.1)
      i18n (~> 0.4)
    faraday (0.8.4)
      multipart-post (~> 1.1)
    fast-stemmer (1.0.1)
    ffi (1.1.5)
    fog (1.5.0)
      builder
      excon (~> 0.14)
      formatador (~> 0.2.0)
      mime-types
      multi_json (~> 1.0)
      net-scp (~> 1.0.4)
      net-ssh (>= 2.1.3)
      nokogiri (~> 1.5.0)
      ruby-hmac
    formatador (0.2.3)
    fssm (0.2.9)
    growl (1.0.3)
    guard (1.3.2)
      listen (>= 0.4.2)
      thor (>= 0.14.6)
    guard-bundler (1.0.0)
      bundler (~> 1.0)
      guard (~> 1.1)
    guard-coffeescript (1.2.0)
      coffee-script (>= 2.2.0)
      guard (>= 1.1.0)
    guard-rails-assets (0.1.3)
      guard
      rails (>= 3.1.1)
      rake
    guard-rspec (1.2.1)
      guard (>= 1.1)
    haml (3.1.7)
    haml_coffee_assets (1.4.6)
      coffee-script (>= 1.0.0)
      sprockets (>= 2.0.3)
      tilt (>= 1.3.3)
    hashie (1.2.0)
    hike (1.2.1)
    httparty (0.8.3)
      multi_json (~> 1.0)
      multi_xml
    httpauth (0.1)
    i18n (0.6.1)
    jbuilder (0.4.3)
      activesupport (>= 3.0.0)
      blankslate (>= 2.1.2.4)
    journey (1.0.4)
    jquery-rails (2.1.1)
      railties (>= 3.1.0, < 5.0)
      thor (~> 0.14)
    json (1.6.7)
    jsonschema (2.0.2)
    jwt (0.1.5)
      multi_json (>= 1.0)
    kgio (2.7.4)
    libwebsocket (0.1.5)
      addressable
    listen (0.4.7)
      rb-fchange (~> 0.0.5)
      rb-fsevent (~> 0.9.1)
      rb-inotify (~> 0.8.8)
    mail (2.4.4)
      i18n (>= 0.4.0)
      mime-types (~> 1.16)
      treetop (~> 1.4.8)
    mime-types (1.19)
    money (5.0.0)
      i18n (~> 0.4)
      json
    mongoid (3.0.5)
      activemodel (~> 3.1)
      moped (~> 1.1)
      origin (~> 1.0)
      tzinfo (~> 0.3.22)
    mongoid-paperclip (0.0.7)
      paperclip (>= 2.3.6)
    mongoid_search (0.3.0)
      fast-stemmer (~> 1.0.0)
      mongoid (>= 3.0.0)
    mongoid_token (1.1.0)
      mongoid (~> 3.0)
    moped (1.2.1)
    multi_json (1.3.6)
    multi_xml (0.5.1)
    multipart-post (1.1.5)
    net-scp (1.0.4)
      net-ssh (>= 1.99.1)
    net-ssh (2.5.2)
    newrelic_rpm (3.4.1)
    nokogiri (1.5.5)
    oauth2 (0.8.0)
      faraday (~> 0.8)
      httpauth (~> 0.1)
      jwt (~> 0.1.4)
      multi_json (~> 1.0)
      rack (~> 1.2)
    omniauth (1.1.1)
      hashie (~> 1.2)
      rack
    omniauth-facebook (1.4.1)
      omniauth-oauth2 (~> 1.1.0)
    omniauth-oauth2 (1.1.0)
      oauth2 (~> 0.8.0)
      omniauth (~> 1.0)
    origin (1.0.7)
    orm_adapter (0.4.0)
    paypal_adaptive (0.3.0)
      json (~> 1.6.0)
      jsonschema (~> 2.0.0)
      rake (~> 0.8)
    polyglot (0.3.3)
    powder (0.1.8)
      thor (>= 0.11.5)
    pusher (0.9.4)
      multi_json (~> 1.0)
      signature (~> 0.1.2)
    rack (1.4.1)
    rack-cache (1.2)
      rack (>= 0.4)
    rack-rewrite (1.2.1)
    rack-ssl (1.3.2)
      rack
    rack-test (0.6.1)
      rack (>= 1.0)
    rails (3.2.2)
      actionmailer (= 3.2.2)
      actionpack (= 3.2.2)
      activerecord (= 3.2.2)
      activeresource (= 3.2.2)
      activesupport (= 3.2.2)
      bundler (~> 1.0)
      railties (= 3.2.2)
    rails-backbone (0.7.2)
      coffee-script (~> 2.2.0)
      ejs (~> 1.0.0)
      railties (>= 3.1.0)
    railties (3.2.2)
      actionpack (= 3.2.2)
      activesupport (= 3.2.2)
      rack-ssl (~> 1.3.2)
      rake (>= 0.8.7)
      rdoc (~> 3.4)
      thor (~> 0.14.6)
    raindrops (0.10.0)
    rake (0.9.2.2)
    rb-fchange (0.0.5)
      ffi
    rb-fsevent (0.9.1)
    rb-inotify (0.8.8)
      ffi (>= 0.5.0)
    rdoc (3.12)
      json (~> 1.4)
    remotipart (1.0.2)
    roadie (2.3.2)
      actionmailer (> 3.0.0, < 3.3.0)
      css_parser
      nokogiri (>= 1.4.4)
      sprockets
    rr (1.0.4)
    rspec (2.9.0)
      rspec-core (~> 2.9.0)
      rspec-expectations (~> 2.9.0)
      rspec-mocks (~> 2.9.0)
    rspec-core (2.9.0)
    rspec-expectations (2.9.1)
      diff-lcs (~> 1.1.3)
    rspec-mocks (2.9.0)
    rspec-rails (2.9.0)
      actionpack (>= 3.0)
      activesupport (>= 3.0)
      railties (>= 3.0)
      rspec (~> 2.9.0)
    ruby-hmac (0.4.0)
    rubyzip (0.9.9)
    sass (3.2.1)
    sass-rails (3.2.5)
      railties (~> 3.2.0)
      sass (>= 3.1.10)
      tilt (~> 1.3)
    selenium-webdriver (2.25.0)
      childprocess (>= 0.2.5)
      libwebsocket (~> 0.1.3)
      multi_json (~> 1.0)
      rubyzip
    shoulda-matchers (1.3.0)
      activesupport (>= 3.0.0)
    signature (0.1.4)
    simple_form (2.0.2)
      actionpack (~> 3.0)
      activemodel (~> 3.0)
    simplecov (0.6.4)
      multi_json (~> 1.0)
      simplecov-html (~> 0.5.3)
    simplecov-html (0.5.3)
    sprockets (2.1.3)
      hike (~> 1.2)
      rack (~> 1.0)
      tilt (~> 1.1, != 1.3.0)
    state_machine (1.1.2)
    stringex (1.4.0)
    thor (0.14.6)
    tilt (1.3.3)
    treetop (1.4.10)
      polyglot
      polyglot (>= 0.3.1)
    tzinfo (0.3.33)
    uglifier (1.2.7)
      execjs (>= 0.3.0)
      multi_json (~> 1.3)
    unicorn (4.3.1)
      kgio (~> 2.6)
      rack
      raindrops (~> 0.7)
    uuidtools (2.1.3)
    warden (1.2.1)
      rack (>= 1.0)
    webmock (1.8.9)
      addressable (>= 2.2.7)
      crack (>= 0.1.7)
    xml-simple (1.1.1)
    xpath (0.1.4)
      nokogiri (~> 1.3)
    yajl-ruby (1.1.0)

PLATFORMS
  ruby

DEPENDENCIES
  active_shipping!
  asset_sync
  awesome_print
  aws-s3
  aws-sdk (~> 1.3.4)
  bson_ext (~> 1.5)
  cancan
  capybara
  coffee-rails (~> 3.2.1)
  compass-rails
  dalli
  database_cleaner
  delayed_job_mongoid
  devise (~> 2.1.0)
  devise-encryptable
  exception_notification
  execjs
  factory_girl_rails
  faker
  growl
  guard
  guard-bundler
  guard-coffeescript
  guard-rails-assets
  guard-rspec
  haml (~> 3.1.4)
  haml_coffee_assets
  jbuilder
  jquery-rails
  mail_view!
  money
  mongoid (~> 3.0)
  mongoid-paperclip
  mongoid_search
  mongoid_slug!
  mongoid_token
  newrelic_rpm
  omniauth-facebook
  paperclip!
  paypal_adaptive (~> 0.3.0)
  powder
  pusher
  rack-rewrite
  rails (= 3.2.2)
  rails-backbone
  rb-fsevent
  remotipart
  roadie
  rr
  rspec-rails (~> 2.9.0)
  sass-rails (~> 3.2.3)
  shoulda-matchers
  simple_form
  simplecov
  state_machine
  uglifier (>= 1.0.3)
  unicorn
  webmock
  yajl-ruby

Mongoid Slug seems to creating the :_slug attribute on the model:

.9.3p125 :029 >   ap Member.last
#<Member:0x007ffd448e1590> {
                             :_id => "5045a65a6245b44b77000010",
                       :_slugs => [ [0] "username4" ],
                  :username => "username4"
}

Do you know what I'm doing wrong? Thank you!

Rewrite to_param to to_slug

In one of my models I used to_param like so

def to_param
 self.token
end

And in special cases I would use the slug aswell. This created an issue because I have no way of getting the slug without to_param. This was my solution:

alias :super_to_param :to_param
def to_param
  self.token
  end

  def to_slug
    "#{self.token}/#{super_to_param()}"
   end

Slug is overwritten if it's already been set in a new document

If you build a new record, set the slug, then save the record, the slug is overwritten.

Would you accept a pull request that prevents the slug from being overwritten if the slugged field was changed from nil ?

Here's what happens at the moment:

class Foo
  include Mongoid::Document
  include Mongoid::Slug

  field :name, :type => String
  slug  :name, :permanent => true
end

f = Foo.new :name => "Nick", :slug => "nick-hoffman"
=> #<Foo _id: 4f0c9df92b58af681600001a, _type: nil, name: "Nick", slug: "nick-hoffman">

f.save
=> true

f.slug == "nick-hoffman"
=> false

f.slug
=> "nick"

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.