我正在使用ActiveRecord开发Rails应用程序。除其他外,我有以下型号:
class Report
has_many :subscriptions
has_many :custom_report_params
end
class CustomReportParam
belongs_to :report
# attributes are: :column_name, :variable_name, :description
end
class Subscription
belongs_to :report
# attributes (among others): :custom_text_field_1[,2,3], :custom_boolean_field_1[,2,3], :custom_date_field_1[,2,3]
end
表格填充如下(例如):
reports
=======
id name
1 Test
2 Test 2
custom_report_params
====================
id report_id column_name variable_name description used
1 1 custom_text_field1 test_param Test Param 1
subscriptions
=============
id report_id custom_text_field_1
1 1 test_param_value
鉴于此背景,我想创建动态方法,让我可以执行以下操作:
r = Report.find(1)
s = r.subscriptions.first #=> returns the subscription object above
# this is the trouble part:
s.test_param #=> should return "test_param_value"
当然,我已经做过的事情就像(过度简化)
s.send(s.report.custom_report_params.used.first.column_name) #=> returns "test_param_value"
所以..简而言之,我想在实例对象上定义动态方法,使用该对象关联来获取方法名称。
如果需要,将很乐意提供更多说明。
我对动态方法很熟悉。我已经做了类似的事情:
["text", "boolean", "date"].each do |type|
(1..3).each do |num|
col_name = "custom_#{type}_field_#{num}"
method_name = "#{col_name}_display
send :define_method, method_name do
case type
when "text"
self.send(col_name)
when "date"
self.send(col_name).try(:to_s, :date_format) || "XXX"
when "boolean"
self.send(col_name) ? "Yes" : "No"
end
end
end
end
任何帮助都将不胜感激。
答案 0 :(得分:0)
试试这个
class Subscription
# ...
def method_missing(mth, *args)
all_params = self.report.custom_report_params
col_name = all_params.find_by(used: true, variable_name: mth)
if col_name
seld.read_attribute(col_name)
else
raise NoMethodError.new("undefined method '#{mth}' for #{self}")
end
# ...
end