Creating a Rails Concern which accepts arguments
30 Nov 2014I wanted to create a Rails Concern which can accept arguments from the parent and/or it’s inherited sub-classes.
Most examples I came across online were simple Concerns which didn’t take any parameters or arguments. So here’s how I went about creating one. Let’s call it Arguable for the sake of this blog post.
Implementation:
module Arguable
extend ActiveSupport::Concern
module ClassMethods
attr_reader :arguable_opts
private
def arguable(opts={})
@arguable_opts = opts
end
end
def do_something
opts = get_arguable_opts
excluded_attrs = opts[:except] || []
included_attrs = opts[:only] || []
custom_attrs = opts[:custom] || {}
#Do something with the attrs here
puts opts
end
def get_arguable_opts
if self.class.arguable_opts.blank? && self.class.superclass.arguable_opts.present?
opts = self.class.superclass.arguable_opts
elsif self.class.arguable_opts.present? && self.class.superclass.arguable_opts.present?
opts = self.class.superclass.arguable_opts.merge(self.class.arguable_opts)
else
opts = self.class.arguable_opts
end
opts || {}
end
end
Usage:
class Shape > ActiveRecord::Base
include Arguable
arguable exclude: [:id]
end
class Circle > Shape
include Arguable
arguable include: [:order], custom: {foo: 'bar'}
end
Circle’s options would then have exclude
available from it’s parent class and all the other include
and custom
options available from the subclass.
> c = Circle.find(1)
> c.do_something # => {exclude: [:id], include: [:order], custom: {foo: 'bar'}}