Skip to content

Instantly share code, notes, and snippets.

@ismasan
Created February 25, 2009 21:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ismasan/70430 to your computer and use it in GitHub Desktop.
Save ismasan/70430 to your computer and use it in GitHub Desktop.
# Put this in an initializer (config/initializers/common_scopes.rb) or library file.
#
module CommonScopes
module ClassMethods
# Sort given fields ASC or DESC
#
# Example:
#
# class Post < ActiveRecord::Base
# extend CommonAr::ClassMethods
#
# sortable_with :title => 'The title', :created_at => 'Created on'
# end
#
# Now you can sort with:
# 'title_asc'
# 'title_desc'
# 'created_at_asc'
# 'created_at_desc'
#
# @posts = Post.sort_with(params[:sort]).paginate(:page => params[:page])
#
# Post.sortable_fields gives you param and human names you can use in your GUI
# Post.sortable_fields #=> {:title_asc => 'The title', :created_at => 'Created on'}
#
def sortable_with(fields = {})
sorts = fields.inject({}) do |h,f|
h[:"#{f.first}_asc"] = "#{f.last} a-z"
h[:"#{f.first}_desc"] = "#{f.last} z-a"
h
end
write_inheritable_attribute(:sortable_fields,sorts)
class_inheritable_reader :sortable_fields
named_scope :sort_with, lambda { |*args|
return {} if args.compact.blank?
k = args.first.to_sym
return {} if !sortable_fields.has_key?(k)
{:order => k.to_s.sub('_desc',' desc').sub('_asc',' asc')} # who has time to learn proper RegEx
}
end
# Search given fields with SQL LIKE
#
# Example:
#
# class Post < ActiveRecord::Base
# extend CommonAr::ClassMethods
#
# likeable_with :title, :body
# end
#
# Now your LIKE queries will look in title and body
# You can combine scopes.
#
# @posts = Post.sort_with(params[:sort]).like(params[:q]).paginate(:page => params[:page])
#
def likeable_with(*fields)
# TODO: validate that schema has these fields
named_scope :like, lambda {|q|
return {} if q.blank? || !q.respond_to?(:to_s)
t = ActiveRecord::Base.connection.quote("%#{q}%")
conditions = fields.collect{|f| "#{f} LIKE #{t}" }.join(' OR ')
{:conditions => conditions}
}
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment