Dynamically creating instance methods:
module RundeckHelper
def self.attr_value(*args)
# Singleton Very Important
singleton_class = class << self; self; end
args.each do |key|
name = key
key = key.to_s.upcase
val = nil
if !ENV[key].nil?
if ENV[key] != ""
val = ENV[key]
else
val = nil
end
elsif !Rails.application.credentials.rundeck.nil?
key2 = key.downcase
if !Rails.application.credentials.rundeck[key2].nil?
val = Rails.application.credentials.rundeck[key2]
else
val = nil
end
elsif !RundeckConfigurationOption.find_by(name: key).nil?
val = RundeckConfigurationOption.find_by(name: key).value
else
val = nil
end
# Send the method to the instance
singleton_class.send(:define_method, name) do
return val
end
end
end
attr_value :base_url, :create_job_id, :project_id, :create_environment_id, :create_instance_id
end
What is this code and how does it work?
Going line by line, this code exists in a Rails module. This is why I believe this was difficult. Creating custom attr_
’s had to be hacked as everything in this module is called as an instance method. The module isn’t instantiated like a class would be. This module in particular has all its methods called as instance methods. The module basically provides helpers to the classes that require
this module.
Breaking down the key lines:
def self.attr_value(*args)
singleton_class = class << self; self; end
singleton_class.send(:define_method, name) do
attr_value :base_url, :create_job_id, :project_id, :create_environment_id, :create_instance_id
These three lines are crucial to creating custom attributes for the variables passed into the attr_value
function.
Starting from the top: def self.attr_value(*args)
- This line defines the method and the method accepts multiple arguments.
- It is an instance method meaning it can be called from within the module
Moving on: singleton_class = class << self; self; end
- We define a singleton_class inside this method to accept from the current object which is the module
Sending Methods: singleton_class.send(:define_method, name) do
- We take the singleton_class we created that is attached to the module and send it the method
- the
name
variable, as seen above, is just the name of the symbol that was passed
Calling the Attribute: attr_value :base_url, :create_job_id, :project_id, :create_environment_id, :create_instance_id
- basically just instantiates the values we need and allows us to use the methods
RundeckHelper.base_url
andself.base_url
returning the value stored in the environment, in the secrets, or in the database.
Top comments (0)