Skip to content

Instantly share code, notes, and snippets.

@BiggerNoise
Created April 1, 2014 02:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save BiggerNoise/9906451 to your computer and use it in GitHub Desktop.
Save BiggerNoise/9906451 to your computer and use it in GitHub Desktop.
Little add in module to make parameter parsing a little easier in Virtus classes.
class Command
include ActiveModel::Validations
include ActiveRecord::Serialization
include Virtus
include VirtusParameters
def initialize(params = {})
super
parse_params params
end
# All your command execution stuff goes here...
end
# You must include this module after including Virtus in your class
module VirtusParameters
ID_PARAMETER = /(\w+)_id$/
extend ActiveSupport::Concern
def parse_params(params)
params.reject{|_,v| v.nil?}.each {|name, value| parse_param(name, value)}
end
def parse_param(name, value)
if (match = ID_PARAMETER.match(name.to_s)) && (ar_class = self.class.active_record_types[match[1].to_sym])
value = ar_class.find(value)
name = match[1].to_sym
end
send("#{name}=", value) if attributes.keys.include?(name)
end
module ClassMethods
def attribute(name, type = Object, options = {})
active_record_types[name] = type if (type.is_a?(Class) && type < ActiveRecord::Base)
super
end
def active_record_types
@active_record_types ||= {}
end
end
end
@BiggerNoise
Copy link
Author

This is a simple add in to make the parsing of parameters in Virtus objects a bit less repetitive. We build command objects based upon Virtus and they often reference ActiveRecord objects.

This add in accomplishes two things when constructing from a hash:

  • If a key in the hash corresponds to an attribute in the class, it is assigned directly
  • If a key in the hash corresponds to an attribute in the class with a _id extension, and that attribute is an ActiveRecord::Base, then the module will find the model for that id.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment