Skip to content

Instantly share code, notes, and snippets.

@lfborjas
Created August 3, 2012 03:30
Show Gist options
  • Save lfborjas/3244069 to your computer and use it in GitHub Desktop.
Save lfborjas/3244069 to your computer and use it in GitHub Desktop.
'cause I want to receive one or the other and actually coerce the value
module CollectionContract
extend ActiveSupport::Concern
module ClassMethods
#I want to be able to say what I expect and do the appropriate casting if needed
#in my specific use-case, these are the only two possible arg types
def collection_method(name, opts = nil, &definition)
opts ||= {}
define_method name do |*args|
rules = {
Array => ->(x){x.to_a},
ActiveRecord::Relation => ->(x){opts[:of].where(id: x.map(&:id))}
}
transformed = args.map do |arg|
rules.reduce(arg) do |last_transformation, current_rule|
expected_type, transformation = current_rule
if !arg.is_a?(expected_type) && opts[:expects] = expected_type
transformation[last_transformation]
else
last_transformation
end
end
end
definition[*transformed]
end
end
end
end
class DoesStuffWithCollections
include CollectionContract
collection_method :extremes, expects: ActiveRecord::Relation, of: User do |users|
users.minmax_by(&:popularity).map(&:username)
end
end
get_array_of_user_ids_from_somewhere = ->(){:magic}
DoesStuffWithCollections.new.extremes(get_array_of_user_ids_from_somewhere)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment