def slugged(*slug_procs)
      options = slug_procs.extract_options!
      raise ArgumentError, "Must provide at least one field or proc to slug" if slug_procs.empty?

      class_attribute :_slug_procs, :_slug_blacklist
      class_attribute :_slugifier, :_slug_id_separator, :_slug_scope

      self._slug_procs = slug_procs.map { |slug_proc| slug_proc.kind_of?(Symbol) ? ->(obj) { obj.send(slug_proc) } : slug_proc }
      self._slugifier = options[:slugifier] || ->(string) { string.to_url }
      self._slug_id_separator = options[:id_separator] || ';'
      self._slug_scope = if options[:scope].kind_of?(Symbol) then
                           ->(record) { record.send(options[:scope]).to_s }
                         elsif options[:scope].kind_of?(Proc) then
                           options[:scope]
                         elsif options[:scope] then
                           raise ArgumentError, ":scope must be a symbol or proc"
                         end
      self._slug_blacklist = Array.wrap(options[:blacklist] || %w( new edit delete destroy ))

      after_save :make_slug
    end
def slugged(*slug_procs)
      options = slug_procs.extract_options!
      raise ArgumentError, "Must provide at least one field or proc to slug" if slug_procs.empty?

      class_attribute :_slug_procs, :_slug_blacklist
      class_attribute :_slugifier, :_slug_id_separator, :_slug_scope

      self._slug_procs = slug_procs.map { |slug_proc| slug_proc.kind_of?(Symbol) ? ->(obj) { obj.send(slug_proc) } : slug_proc }
      self._slugifier = options[:slugifier] || ->(string) { string.to_url }
      self._slug_id_separator = options[:id_separator] || ';'
      self._slug_scope = if options[:scope].kind_of?(Symbol) then
                           ->(record) { record.send(options[:scope]).to_s }
                         elsif options[:scope].kind_of?(Proc) then
                           options[:scope]
                         elsif options[:scope] then
                           raise ArgumentError, ":scope must be a symbol or proc"
                         end
      self._slug_blacklist = Array.wrap(options[:blacklist] || %w( new edit delete destroy ))

      after_save :make_slug
    end
Call this method to indicate that your model uses slugging. Pass a list of
 **slug generators**: either symbols (method names) or procs that return
 strings. These strings will be used to generate the slug. You must pass at
 least one generator. If you pass more than one, the first one that returns
 a unique slug will be used.

 The generator does not need to sanitize or parameterize its output; the
 `:slugifier` option can be used to override the default parameterization.

 In the event that no generator returns a unique slug, the slug returned by
 the last generator will have the ID of the record appended to it. The ID
 and the slug will be separated by the `:id_separator` option (semicolon by
 default). _This_ slug is hopefully unique, because if not, an exception is
 raised.

 Slugs are automatically generated before validation and updated when
 necessary.

 h2. Scopes

 You can scope your slugs to certain URL subpaths using the `:scope`
 option. The `:scope:` option takes a method name or a `Proc` that, when
 run, returns a string that scopes the uniqueness constraint of a slug.
 Rather than being globally unique, the slug must only be unique among
 other slugs that share the same scope.

 **Important note:** The method or `Proc` that you use for the `:scope`
 option should return the portion of the URL preceding the slug, _slash
 included_. Let's say you have slugged your `User` model's `login` field,
 and you have two scopes: customers and merchants. In that case, you would
 want the `:scope` method/proc to return either "clients/" or "merchants/".

 The string returned by the `:scope` option will be used to build the full
 URL to an object. If you have a client `User` with login "fancylad", a
 call to `to_param` will return "clients/fancyland". The scope portion of
 that URL path is used un-sanitized, un-escaped, and un-processed. It is
 therefore up to _you_ to ensure your scopes are valid URL strings, using
 say `String#to_url` (included as part of this gem).

 @overload slugged(generator, ..., options={})
   @param [Proc, Symbol] generator If it's a `Symbol`, indicates a method
     that will be called that will return a `String` to be used for the
     slug.
   @param [Hash] options Additonal options that control slug generation.
   @option options [Proc] :slugifier (&:to_url) A proc that, when given a
     string, produces a URL-safe slugged version of that string.
   @option options [String] :id_separator (';') A separator to be used in
     the "last-resort" slug between the slug and the model ID. This should
     be an URL-safe character that would never be produced by your
     slugifier.
   @option options [Symbol, Proc] :scope A method name or `Proc` to run
     (receives the object being slugged) that returns a string. Slugs must
     be unique across all objects for which this method/proc returns the
     same value. If not provided, slugs must be globally unique for this
     model. The string returned should be equal to the portion of the URL
     path that precedes the slug.
   @option options [Array<String>, String] :blacklist ([ 'new', 'edit', 'delete', 'destroy' ])
     A list of slugs that are disallowed. You would use this to prevent
     slugs from sharing the same name as actions in your resource
     controller.
 @raise [ArgumentError] If no generators are provided.