Rails5中如何仅保存时间字段而非带日期的时间?
如何在Rails 5中仅保存时间字段的时间部分
嘿,我之前在Rails项目里也遇到过一模一样的问题——默认情况下,要是给datetime类型的字段传纯时间字符串,Rails会自动补一个默认日期(比如你提到的Sat, 01 Jan 2000 07:25:00 UTC +00:00),要只保留时间部分,有几个实用的方案:
方案1:修改数据库字段为time类型(推荐)
这是最根本的解决办法,既然你的字段本来就只需要存时间,直接把数据库字段类型改成time,就能让Rails自动处理,不会附加默认日期。
先生成迁移文件:
rails generate migration ChangeStartTimeAndEndTimeToTimeInMyModels
然后编辑迁移文件内容:
class ChangeStartTimeAndEndTimeToTimeInMyModels < ActiveRecord::Migration[5.2] def change change_column :my_models, :start_time, :time change_column :my_models, :end_time, :time end end
执行迁移:
rails db:migrate
之后你再执行MyModel.save(start_time: '12:34'),数据库里就只会存储时间部分,不会带上多余的默认日期了。
方案2:用回调在保存前剥离日期(适合无法改数据库的场景)
如果因为历史原因不能修改数据库字段类型,你可以在模型里加一个before_save回调,手动提取时间部分再保存:
class MyModel < ApplicationRecord before_save :keep_only_time_part private def keep_only_time_part # 提取start_time的时分秒部分 if start_time.present? self.start_time = Time.parse(start_time.strftime("%H:%M:%S")) end # 同理处理end_time if end_time.present? self.end_time = Time.parse(end_time.strftime("%H:%M:%S")) end end end
这样保存后,数据库里的日期部分还是会保留默认值,但时间部分完全是你想要的。如果只是需要展示或业务逻辑里用时间部分,这个方法也能满足需求。
方案3:在模型中显式指定属性类型
你可以在模型里用attribute方法明确声明字段为时间类型,让Rails在处理时更精准:
class MyModel < ApplicationRecord attribute :start_time, :time attribute :end_time, :time end
这个方法配合time类型的数据库字段使用效果最好,能确保Rails始终把字段当作纯时间来处理,不会自动补全日期。
额外注意点
- 如果你是通过表单提交时间,确保表单里传的是纯时间字符串(比如
"12:34"),而不是带日期的格式。 - 在强参数(strong params)里要允许
start_time和end_time参数通过:
def my_model_params params.require(:my_model).permit(:start_time, :end_time, ...) end
内容的提问来源于stack exchange,提问作者Chakreshwar Sharma
相关产品推荐
相关产品推荐

