Reputation: 321
I am modelling a report as a class and each column value as an accessor. Each value in the report needs to be accessed from the database. But this makes the class look quite fat and RubyMine warns me of too many methods in class.
class Report
attr_accessor :name, :col1, :col2, :col3 .... :col15
def col1
db.find({x: 1})['some_var']
end
def col2
db.find({y: 4})['some_other_var']
end
and so forth for each attribute...
end
Since each getter is essentially single line that makes call to database, is there a simpler way to declare these vars without being in a method?
I don't want to set these in the initialize method as these reports will be subclassed and child reports will not have all/some of these attributes.
Upvotes: 0
Views: 166
Reputation: 104
You can use meta-programming to create attr_accessor like methods on the fly.
For Example:
class Report
def initialize(attributes)
attributes.each do |attribute|
define_singleton_method :"#{attribute}" do |hash_param, string_param|
db.find(hash_param)[string_param]
end
end
end
end
Then you can create new report object and pass attribute names as follow:
r = Report.new(["n","m"])
Now you can call n
and m
methods on the r
object
r.m({val1: "val1"}, "val2")
r.n({val2: "val1"}, "val2")
Upvotes: 1
Reputation: 11216
@Rahul based on answer to my question, the only advice I can give here then is to use best OOP design principles. Subclass and modularize where possible as well as using ruby meta-programming. If you need the methods, they have to be written somewhere. But if you only need getters, consider attr_reader
instead, unless you'll need setters too.
If you can get the column names you can use dynamic method definition with something like this assuming db
is magically defined somewhere you have not made clear, we'll assume it's a connection to the database.
class Report
db.column_names.each do |col|
define_method(col.to_sym) { db.find(options={}) }
end
end
If you just want RubyMine to stop nagging you, I assume it's using rubocop and you can see this post for how to override rules.
https://www.jetbrains.com/help/ruby/2017.1/rubocop.html
or
https://github.com/rubocop-hq/rubocop
Upvotes: 0