如何覆盖“新"Rails 模型的方法 [英] How to override "new" method for a rails model

查看:33
本文介绍了如何覆盖“新"Rails 模型的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的 rails 应用程序中,我有一个带有 start_date 和 end_date 的模型.如果用户选择 2010 年 1 月 1 日作为开始日期,选择 2010 年 1 月 5 日作为结束日期,我希望创建模型的 5 个实例(选择的每一天一个).所以它看起来像

In my rails app I have a model with a start_date and end_date. If the user selects Jan 1, 2010 as the start_date and Jan 5, 2010 as the end_date, I want there to be 5 instances of my model created (one for each day selected). So it'll look something like

Jan 1, 2010
Jan 2, 2010
Jan 3, 2010
Jan 4, 2010
Jan 5, 2010

我知道处理此问题的一种方法是在控制器中执行循环.像……

I know one way to handle this is to do a loop in the controller. Something like...

# ...inside controller
start_date.upto(end_date) { my_model.new(params[:my_model]) }

然而,我想保持我的控制器瘦,而且我想将模型逻辑保留在它之外.我猜我需要覆盖模型中的新"方法.这样做的最佳方法是什么?

However, I want to keep my controller skinny, plus I want to keep the model logic outside of it. I'm guessing I need to override the "new" method in the model. What's the best way to do this?

推荐答案

正如@brad 所说,您绝对不想覆盖初始化.尽管您可以覆盖 after_initialize,但这看起来并不像您在这里想要的那样.相反,您可能希望像@Pasta 建议的那样向类添加工厂方法.因此,将其添加到您的模型中:

As @brad says, you definitely do not want to override initialize. Though you could override after_initialize, that doesn't really look like what you want here. Instead, you probably want to add a factory method to the class like @Pasta suggests. So add this to your model:

def self.build_for_range(start_date, end_date, attributes={})
  start_date.upto(end_date).map { new(attributes) }
end

然后将其添加到您的控制器中:

And then add this to your controller:

models = MyModel.build_for_range(start_date, end_date, params[:my_model])
if models.all?(:valid?)
  models.each(&:save)
  # redirect the user somewhere ...
end

这篇关于如何覆盖“新"Rails 模型的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆