This module, when included in a Mongoid model, generates a URL slug or permalink based on a field or set of fields.
Here we have a book model that embeds many authors:
class Book include Mongoid::Document include Mongoid::Slug field :title slug :title embeds_many :authors end class Author include Mongoid::Document include Mongoid::Slug field :first_name field :last_name slug :first_name, :last_name embedded_in :book, :inverse_of => :authors end
The finders in our controllers would possibly look like:
class BooksController def show @book = Book.where(:slug => params[:id]).first end # and so on end class AuthorsController def show @book = Book.where(:slug => params[:book_id]).first @author = @book.authors.where(:slug => params[:id]).first end # and so on end
If you are wondering why I did not include a find_by_slug helper, read on.
To demo some more functionality in the console:
>> book = Book.create(:title => "A Thousand Plateaus") >> book.to_param "a-thousand-plateaus" >> book.update_attributes(:title => "Anti Oedipus") >> book.to_param "anti-oedipus" >> Book.where(:slug => 'anti-oedipus').first #<Book _id: 4c23b1f7faa4a7479a000009, slug: "anti-oedipus", title: "Anti Oedipus"> >> author = book.authors.create(:first_name => "Gilles", :last_name => "Deleuze") >> author.to_param => "gilles-deleuze" >> author.update_attributes(:first => "Félix", :last_name => "Guattari") >> author.to_param => "félix-guattari" >> book.authors.where(:slug => 'felix-guattari).first => #<Author _id: 4c31e362faa4a7050e000003, slug: "félix-guattari", last_name: "Guattari", first_name: "Félix">
Last but not least, check out the specs and the sample models I used there for more examples.