我正在Rails中为一个内部项目构建一个新的应用程序,该项目每年根据客户的要求略有变化。年份之间的任何更改都将在模型中发生(添加/删除列,格式,报告等)。我的计划是将其构建到今年的要求,并且每年都会继续创建一个新的模型和迁移(例如Sample2019Record,Sample2020Record ),它将封装当年的需求。该应用程序还需要呈现上一年的数据,并且所有数据都基于年份确定范围,这意味着无需呈现或查询多年数据。我不希望每年都创建一个新的应用程序,因为这是需要维护的更多应用程序。
所以我的想法是将年份包含在URL( / 2018 / sample / new或/ sample / new?year = 2018 )中并根据年份解析模型(“Sample#” {年份}记录“)。导轨可以安全地处理这个问题,并且有一个宝石可以帮助这种方法吗?
这是我想出的,感谢您的建议。
的routes.rb
get '/:year/samples', to: 'samples#index', as: :samples, defaults: { year: Time.current.year }
路线将始终默认为当前年份
application_controller.rb
before_action :check_year
def check_year
if params.has_key?(:year)
if "Sample#{params[:year]}Record".safe_constantize.nil?
redirect_to root_path(year: Time.current.year), notice: "Invalid Year"
end
else
redirect_to root_path(year: Time.current.year), notice: "Invalid Year"
end
end
def get_sample_record(year=Time.current.year)
"Sample#{year}Record".safe_constantize
end
添加了一个before_action来检查year参数,并添加了get_sample_record
方法来安全地对可以从具有可选年份的任何控制器调用的记录进行同步:
sample_controller.rb
sample_2018_record = get_sample_record
sample_2018_record.count
#> 304
sample_2017_record = get_sample_record 2017
sample_2017_record.count
#> 575683
如果通过无效年份,结果将为nil
,因此我将在控制器中处理检查。
答案 0 :(得分:1)
正如@DaveNewton所说,只要你在不同的表中保存与不同年份要求相对应的数据,这似乎应该可以正常工作。其他一些观察结果:
Rails有一个辅助方法constantize
,用于从字符串中解析模型:
klass_name = "Sample#{year}Record"
record = klass_name.constantize.new()
将使变量record
成为与year
变量对应的类的实例。您可能会发现使用Factory模式封装流程很有帮助。
另外。小心你如何命名和组织你的文件。在使用Rails感染器处理名称中包含数字的类时,您可能会发现this thread有用。与Rails合作的一个重要部分是允许它的魔力为你工作,而不是在不知不觉中试图反对它。
作为一般而非Rails特定的建议,我还要考虑如何为记录定义一个共同的公共接口,这些记录将持续多年。一个包含
之类的代码库if record.instance_of? Sample2018Record
record.my_2018_method
elsif record.instance_of? Sample2019Record
record.my_method_only_relevant_to_2019
...
将变得非常难以推理,特别是对于几年后加入的开发人员。 Ruby拥有非常强大的工具,可以帮助您非常有效地保护类型。