lib/slugalicious.rb in slugalicious-2.0.0 vs lib/slugalicious.rb in slugalicious-2.1.0
- old
+ new
@@ -1,9 +1,9 @@
require 'slugalicious_generator'
require 'stringex'
-# Adds the @slugged@ method to an @ActiveRecord::Base@ subclass. You can then
+# Adds the `slugged` method to an `ActiveRecord::Base` subclass. You can then
# call this method to add slugging support to your model. See the
# {ClassMethods#slugged} method for more details.
#
# @example Basic example of a slugged model
# class Widget < ActiveRecord::Base
@@ -45,11 +45,11 @@
# preceding the slug.
# @return [ActiveRecord::Base, nil] The object with that slug, or `nil` if
# not found.
def find_from_slug(slug, scope=nil)
- Slug.from_slug(self, scope, slug).first.try(:sluggable)
+ Slug.from_slug(self, scope, slug).first.try!(:sluggable)
end
# Locates a record from a given path, that consists of a slug and its scope,
# as would appear in a URL path component.
#
@@ -65,66 +65,66 @@
end
protected
# Call this method to indicate that your model uses slugging. Pass a list of
- # *slug generators*: either symbols (method names) or procs that return
+ # **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.
+ # `: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
+ # 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
+ # 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@
+ # **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,
+ # 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/".
+ # 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
+ # 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).
+ # 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
+ # @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
+ # @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' ])
+ # @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.
@@ -143,43 +143,43 @@
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 ))
+ self._slug_blacklist = Array.wrap(options[:blacklist] || %w( new edit delete destroy ))
after_save :make_slug
end
end
def slug_object
- slugs.loaded? ? slugs.detect(&:active) : slugs.active.first
+ slugs.loaded? ? slugs.detect(&:active?) : slugs.active.first
end
private :slug_object
- # @return [String, nil] The slug for this object, or @nil@ if none has been
+ # @return [String, nil] The slug for this object, or `nil` if none has been
# assigned.
def slug
Rails.cache.fetch("Slug/#{self.class.to_s}/#{id}/slug") do
- slug_object.try(:slug)
+ slug_object.try!(:slug)
end
end
# @return [String, nil] The full slug and path for this object, with scope
- # included, or @nil@ if none has been assigned.
+ # included, or `nil` if none has been assigned.
def slug_with_path
Rails.cache.fetch("Slug/#{self.class.to_s}/#{id}/slug_with_path") do
slug_object ? (slug_object.scope.to_s + slug_object.slug) : nil
end
end
# @param [String] slug A slug for this object.
- # @return [true, false, nil] @true@ if the slug is the currently active one
- # (should not redirect), @false@ if it's inactive (should redirect), and
- # @nil@ if it's not a known slug for the object (should 404).
+ # @return [true, false, nil] `true` if the slug is the currently active one
+ # (should not redirect), `false` if it's inactive (should redirect), and
+ # `nil` if it's not a known slug for the object (should 404).
def active_slug?(slug)
@active_slug ||= begin
slug = if slugs.loaded? then
slugs.detect { |s| s.slug.downcase == slug.downcase }
@@ -198,11 +198,11 @@
def make_slug
slugs_in_use = if slugs.loaded? then
slugs.map(&:slug)
else
- slugs.select(:slug).all.map(&:slug)
+ slugs.select(:slug).map(&:slug)
end
# grab a list of all potential slugs derived from the generators
potential_slugs = self.class._slug_procs.map { |slug_proc| slug_proc[self] }.
compact.
@@ -230,21 +230,22 @@
# grab a list of all the slugs we can't use
scope = Slug.select(:slug).where(sluggable_type: self.class.to_s, slug: potential_slugs)
if self.class._slug_scope then
scope = scope.where(scope: self.class._slug_scope[self])
end
- taken_slug_objects = scope.all
+ taken_slug_objects = scope
# subtract them out from all the potential slugs to make the available slugs
available_slugs = potential_slugs - taken_slug_objects.map(&:slug)
# no slugs available? nothing much else we can do
raise "Couldn't find a slug for #{self.inspect}; tried #{potential_slugs.join(', ')}" if available_slugs.empty?
slugs.update_all(active: false)
Slug.create!(sluggable: self,
slug: available_slugs.first,
active: true,
- scope: self.class._slug_scope.try(:call, self))
+ scope: self.class._slug_scope.try!(:call, self))
+ slugs(true)
end
@active_slug = nil
end
end