我将报告建模为一个类,并将每个列值建模为一个访问器。报告中的每个值都需要从数据库中访问。但这使类看起来很胖,RubyMine警告我类中的方法太多。
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
由于每个getter本质上是对数据库进行调用的单行,是否有更简单的方法来声明这些var,而无需使用方法?
我不想在initialize方法中进行设置,因为这些报表将被子类化,子报表将不具有所有/某些这些属性。
答案 0 :(得分:1)
您可以使用元编程来动态创建attr_accessor之类的方法。
例如:
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
然后,您可以创建新的报表对象并按如下所示传递属性名称:
r = Report.new(["n","m"])
现在您可以在n
对象上调用m
和r
方法
r.m({val1: "val1"}, "val2")
r.n({val2: "val1"}, "val2")
答案 1 :(得分:0)
@Rahul基于对我的问题的回答,那么我在这里只能给出的建议是使用最佳的OOP设计原则。尽可能进行子类化和模块化,以及使用ruby元编程。如果需要这些方法,则必须将它们编写在某处。但是,如果只需要吸气剂,则考虑使用attr_reader
,除非也需要吸气剂。
如果可以获取列名,则可以使用动态方法定义以及类似的方法,假设db
是在您不清楚的地方神奇定义的,我们将假定它是与数据库的连接。
class Report
db.column_names.each do |col|
define_method(col.to_sym) { db.find(options={}) }
end
end
如果您只是想让RubyMine停止对您的困扰,我假设它正在使用rubocop,并且您可以看到this post来了解如何覆盖规则。
https://www.jetbrains.com/help/ruby/2017.1/rubocop.html
或