In a recent task, we had generated several models that share some common behavior. However, inheritance was not an option as the names of attributes were different for each class.
In such a case, you need to provide functionality for each class separately. Much of the code will be duplicated in methods pertaining to each class, which runs against the DRY principle.
In Ruby, a class called "Object" comes to the rescue. Using this class, we can retrieve a class (to be used exactly as a class) given its name (as a string):
@klass = Object.const_get("class_name")You can create a new instance of the class:
@instance = @klass.send "new"
You can then assign values to attributes by their name (string):
@instance.attributes={attribute_symbol => attribute_value}You can also invoke a method directly on the class such as "find" or "all":
@klass.send "find", parameter_1, parameter_2, ...
In the following snippet, we call a method from a module to create a link between any object and a tagging object. We can use this in our controllers several times, passing relevant parameters to each:
tag_object( 'SubjectTag', :subject_id, :tag_id, 312, 105)
The code implementing this function can be understood knowing the above hints:
def tag_object(tag_class, id_symbol, tag_symbol, id, tag)
@klass = Object.const_get(tag_class)
if (@klass.send "find", :all, :conditions => {id_symbol => id, tag_symbol => tag}).length > 0 then
return false
end # if
new_tag = @klass.send "new"
new_tag.attributes={id_symbol => id, tag_symbol => tag}
return new_tag.save
end
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.