I'm trying to do something like this, where the send method's block has block arguments:
klass.attribute_names.each do |attribute|
klass.send(define_method("next_by_" + attribute) { object, user = nil
if user
klass.joins(:users).where("#{attribute} > ?", object.send(attribute)).where(users: {id: user.id}).first
else
klass.where("#{attribute} > ?", object.send(attribute)).first
end
})
end
Which isn't valid Ruby. Is this possible to do, and if so what is the best way to do so?
EDIT: I realize the reserved keyword "class" here. It is simply for illustration purposes. I've changed it to klass to prevent further confusion.
More detail, this is the entire file:
module Helpers::ResourceRecordHelper
# Remove this and call upon the module's methods to include instead to fix performance hit
def self.included(source)
define_class_methods(source)
end
def define_class_methods(source)
source.attribute_names.each do |attribute|
# These defined methods never reach the class
define_method("next_by_" + attribute) { object, user = nil
if user
self.class.joins(:users).where("#{attribute} > ?", object.send(attribute)).where(users: {id: user.id}).first
else
self.class.where("#{attribute} > ?", object.send(attribute)).first
end
}
define_method("previous_by_" + attribute) do object, user = nil
if user
self.class.joins(:users).where("#{attribute} < ?", object.send(attribute)).where(users: {id: user.id}).last
else
self.class.where("#{attribute} < ?", object.send(attribute)).last
end
end
end
def source.next(object, user = nil)
source.next_by_id(object, user)
end
def source.previous(object, user = nil)
source.previous_by_id(object, user)
end
end
extend self
end
classthis should work. Although it's a little tricky to understand, since you'd have to know that define_method returns a symbol that can be passed to send.send) in another.