Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: AaronLasseigne/with_order
base: cd72db950e
...
head fork: AaronLasseigne/with_order
compare: 7130095e3e
Checking mergeability… Don't worry, you can still create the pull request.
  • 4 commits
  • 7 files changed
  • 0 commit comments
  • 1 contributor
View
2  .gitignore
@@ -4,3 +4,5 @@ Gemfile.lock
pkg/*
*.swp
spec/dummy/log/*.log
+.yardoc
+doc
View
1  .yardopts
@@ -0,0 +1 @@
+--no-private --markup markdown
View
28 lib/with_order/action_view_extension.rb
@@ -2,6 +2,34 @@ module WithOrder
module ActionViewExtension
include WithOrder::HashExtraction
+ # Create a link tag that changes how the data is ordered.
+ #
+ # @overload link_with_order(text, scope, field, options = {})
+ # @param [String] text The text to display.
+ # @param [ActiveRecord::Relation, Array] scope The data being ordered on.
+ # @param [Symbol] field The field represented by this sortable link.
+ # @param [Hash] options Options for the link.
+ # @option options [String] :dir Permanently fix the direction of the order.
+ #
+ # @example
+ # <%= link_with_order('First Name', @data, :first_name) %> # => <a href="controller/action?order=first_name-desc">First Name</a>
+ #
+ # @overload link_with_order(scope, field, options = {}, &block)
+ # @param [ActiveRecord::Relation, Array] scope The data being ordered on.
+ # @param [Symbol] field The field represented by this sortable link.
+ # @param [Hash] options Options for the link.
+ # @option options [String] :dir Permanently fix the direction of the order.
+ # @param [Block] block The output for display.
+ #
+ # @example
+ # <%= link_with_order(@data, :first_name) do %>
+ # <strong>First Name</strong>
+ # <% end %>
+ # # => <a href="controller/action?order=first_name-desc"><strong>First Name</strong></a>
+ #
+ # @return [String] An HTML anchor tag with the field sorting information.
+ #
+ # @since 0.1.0
def link_with_order(*args, &block)
text = scope = field = html_options = nil
View
4 lib/with_order/active_record_extension.rb
@@ -1,4 +1,5 @@
module WithOrder
+ # @private
module ActiveRecordExtension
extend ActiveSupport::Concern
@@ -7,12 +8,15 @@ class << self
alias_method_chain :inherited, :with_order
end
+ # Attach the ActiveRecord extensions to children of ActiveRecord that were initiated before we loaded WithOrder.
self.descendants.each do |descendant|
descendant.send(:include, WithOrder::ActiveRecordModelExtension) if descendant.superclass == ActiveRecord::Base
end
end
+ # @private
module ClassMethods
+ # Attaches the ActiveRecord extensions to children of ActiveRecord so we don't pollute ActiveRecord::Base.
def inherited_with_with_order(base)
inherited_without_with_order(base)
base.send(:include, WithOrder::ActiveRecordModelExtension) if base.superclass == ActiveRecord::Base
View
35 lib/with_order/active_record_model_extension.rb
@@ -3,9 +3,39 @@ module ActiveRecordModelExtension
extend ActiveSupport::Concern
module CurrentOrder
+ # @return [Hash<:field, :dir, :param_namespace>] Properties relating to the current ordering.
+ #
+ # @since 0.1.0
attr_accessor :current_order
end
+ # Attaches an order to the scope.
+ #
+ # @example
+ # Account.with_order(params, default: :full_name, fields: {full_name: 'first_name ASC, last_name ASC'})
+ #
+ # @scope class
+ # @overload with_order(order, options={})
+ # @param [Hash, String, Symbol] order Defines the field to sort on. Hashes are expected to have
+ # an `:order` key. Strings can contain a direction by using a dash between the field name and
+ # the desired sorting direction (e.g. 'first_name-asc').
+ # @param [Hash] options
+ # @option options [String, Symbol] :default Defines a default field to sort on.
+ # @option options [Symbol] :param_namespace When `order` is a Hash this defines a namespace for the `:order` param.
+ # @option options [Hash<String>] :fields A mapping of field names to custom orderings.
+ #
+ # @example Where order is a Hash. Usually the Hash would be `params`.
+ # Account.with_order({order: 'first_name-asc'})
+ #
+ # @example Where order is a String.
+ # Account.with_order('first_name-asc')
+ #
+ # @example Where order is a Symbol.
+ # Account.with_order(:first_name)
+ #
+ # @return [ActiveRecord::Relation]
+ #
+ # @since 0.1.0
included do
self.scope :with_order, ->(order = nil, options = {}) {
relation = self.scoped.extending do
@@ -16,6 +46,7 @@ module CurrentOrder
end
order = (order || options[:default]).to_s
+ # See the accessor above in CurrentOrder for documentation.
define_method :current_order do
field = dir = nil
field, dir = order.match(/^(.*?)(?:-(asc|desc))?$/i).captures if order
@@ -32,6 +63,7 @@ module CurrentOrder
end
end
+ # Attach current_order to the created Array so we don't lose the data.
def to_a
a = super.extend(CurrentOrder)
a.current_order = self.current_order
@@ -39,8 +71,10 @@ def to_a
end
end
+ # move on if we don't have a field to order on
return relation unless relation.current_order[:field]
+ # generate the order text
order_text = ''
if options[:fields] and options[:fields][relation.current_order[:field]]
order_text = options[:fields][relation.current_order[:field]]
@@ -55,6 +89,7 @@ def to_a
order_text = "#{field} ASC"
end
+ # add the order and reverse direction if necessary
if relation.current_order[:dir].try(:downcase) == :desc
relation.reorder(order_text).reverse_order
else
View
1  lib/with_order/engine.rb
@@ -1,4 +1,5 @@
module WithOrder
+ # @private
class Engine < ::Rails::Engine
end
end
View
15 lib/with_order/hash_extraction.rb
@@ -1,5 +1,20 @@
module WithOrder
+ # @private
module HashExtraction
+ # Extracts the value from a hash and takes nesting into account.
+ #
+ # @param [Hash] hash The hash to search.
+ # @param [String, Symbol] key The key or nested key to search for.
+ #
+ # @return [Object, nil]
+ #
+ # @example Key is a symbol.
+ # extract_hash_key({foo: 'bar'}, :foo) # => 'bar'
+ #
+ # @example Key is a string with nesting.
+ # extract_hash_key({foo: {bar: 'baz'}}, 'foo[:bar]') # => 'baz'
+ #
+ # @since 0.1.0
def extract_hash_value(hash, key)
return hash[key] if key.is_a?(Symbol)

No commit comments for this range

Something went wrong with that request. Please try again.