ruby-on-rails - 在一个 POST 请求中创建多个 ActiveRecord 对象时的最佳做法是什么
问题描述
在我们的 rails 5.2.3 和 ruby 2.6.0 应用程序中,我们正在开发一个预订系统,用户可以在其中发布他们可用的时间和日期。要求的功能之一是用户可以输入一段日期,即开始和结束日期。我的问题是为所有这些日期创建 ActiveRecord 对象的最佳做法是什么。目前我拥有整个解决方案的这一部分,因为我决定在进一步研究之前获得一些输入/反馈。
#ShiftController
def create
start = DateTime.parse(shift_params)
stop = DateTime.parse(shift_params)
days_between = (start.to_date..stop.to_date).count
shifts_to_save = []
days_between.times do |i|
stop_time = stop - days_between + i
shift = Shift.new(food: params[:shift][:food], start_time: start, end_time: stop_time)
shifts_to_save.push shift
current_user.shifts << shift
end
end
如果我添加一个迭代shifts_to_save
数组并保存每个条目的片段,然后在迭代所有班次后显示错误,我认为它会按预期工作。但是这个解决方案并不让我感到骄傲,也不觉得它像红宝石一样。
解决方案
您可以在数据库事务中包装多条记录的创建。这将更快,并确保所有记录要么一起创建要么不创建,例如:
Shift.transaction do
# create shifts inside here using save! or create! to ensure rollback upon failure
end
然而,将上述逻辑填充到事务中感觉就像一大块程序代码。识别所涉及的领域概念并将它们移动到模型层以便于理解和独立的单元测试可能会更 Rails-y,例如:
#ShiftController
def create
start = DateTime.parse(shift_params)
stop = DateTime.parse(shift_params)
Shift.indicate_availability(
user: current_user,
start: start,
stop: stop,
food: params[:food]
)
end
推荐阅读
- java - 从 dynamoDB 返回更新的项目
- php - php是否可以在每个页面上包含一个引导导航栏,但是使用额外的代码来使代码显示哪个页面处于活动状态
- php - Laravel 已弃用错误:idn_to_ascii(): INTL_IDNA_VARIANT_2003 已弃用
- openssl - 将私钥转换为 PKCS#8
- react-native - 当父组件使用 withNavigation 时,navigation.goBack() 是否在子组件中工作?
- android - 扩展的 RecycleView 滞后
- c++ - 如何从代码中删除类并仍然使其工作?
- c# - Umbraco ADFS 集成 (OpenIdConnect) GroupSid 未设置?
- admob - 对 Sniffer/Modder/Hacker 隐藏 Admob APP ID
- ruby-on-rails - 如何使redirect_to 以远程形式工作?