gpt4 book ai didi

ruby-on-rails - 在 Rails 模型中设置和获取虚拟属性

转载 作者:行者123 更新时间:2023-12-04 06:03:42 25 4
gpt4 key购买 nike

我正在寻找一种 rails-y 方法来处理以下问题:

两个datetime 中的属性事件 模型:

start_at: datetime
end_at: datetime

我想使用 3 个字段以表格形式访问它们:
event_date
start_time
end_time

我遇到的问题是如何使实际和虚拟属性保持“同步”,以便可以通过表单和/或直接通过 start_at 更新模型。 & end_at .
class Event < ActiveRecord::Base
attr_accessible :end_at, :start_at, :start_time, :end_time, :event_date
attr_accessor :start_time, :end_time, :event_date

after_initialize :get_datetimes # convert db format into accessors
before_validation :set_datetimes # convert accessors into db format

def get_datetimes
if start_at && end_at
self.event_date ||= start_at.to_date.to_s(:db) # yyyy-mm-dd
self.start_time ||= "#{'%02d' % start_at.hour}:#{'%02d' % start_at.min}"
self.end_time ||= "#{'%02d' % end_at.hour}:#{'%02d' % end_at.min}"
end
end

def set_datetimes
self.start_at = "#{event_date} #{start_time}:00"
self.end_at = "#{event_date} #{end_time}:00"
end
end

哪个有效:
1.9.3p194 :004 > e = Event.create(event_date: "2012-08-29", start_time: "18:00", end_time: "21:00")

=> #<Event id: 3, start_at: "2012-08-30 01:00:00", end_at: "2012-08-30 04:00:00", created_at: "2012-08-22 19:51:53", updated_at: "2012-08-22 19:51:53">

直到直接设置实际属性( end_at 在验证时设置回 end_time):
1.9.3p194 :006 > e.end_at = "2012-08-30 06:00:00 UTC +00:00"
=> "2012-08-30 06:00:00 UTC +00:00"
1.9.3p194 :007 > e
=> #<Event id: 3, start_at: "2012-08-30 01:00:00", end_at: "2012-08-30 06:00:00", created_at: "2012-08-22 19:51:53", updated_at: "2012-08-22 19:51:53">
1.9.3p194 :008 > e.save
(0.1ms) BEGIN
(0.4ms) UPDATE "events" SET "end_at" = '2012-08-30 04:00:00.000000', "start_at" = '2012-08-30 01:00:00.000000', "updated_at" = '2012-08-22 20:02:15.554913' WHERE "events"."id" = 3
(2.5ms) COMMIT
=> true
1.9.3p194 :009 > e
=> #<Event id: 3, start_at: "2012-08-30 01:00:00", end_at: "2012-08-30 04:00:00", created_at: "2012-08-22 19:51:53", updated_at: "2012-08-22 20:02:15">
1.9.3p194 :010 >

我的假设是我还需要 自定义“实际”属性的 setter 但我不确定如何在不破坏默认行为的情况下做到这一点。想法?也许有更多的“Rails-y”“callback-y”方式来处理这个问题?

最佳答案

这是我的看法。我还没有用 ActiveRecord 测试过它,但我留下了评论。希望这可以帮助。

class Event < ActiveRecord::Base

attr_accessible :end_at, :start_at, :start_time, :end_time, :event_date
attr_accessor :start_time, :end_time, :event_date

def start_time
@start_time || time_attr_from_datetime(start_at)
end

def start_time=(start_time_value)
@start_time = start_time_value
set_start_at
end

def end_time
@end_time || time_attr_from_datetime(end_at)
end

def end_time=(end_time_value)
@end_time = @end_time_value
set_end_at
end

def event_date
@event_date || start_at.to_date.to_s(:db)
end

def event_date=(event_date_value)
@event_date = event_date_value
set_start_at
set_end_at
end

def start_at=(start_at_value)
write_attribute(:start_at, start_at_value) # Maybe you need to do write_attribute(:start_at, DateTime.parse(start_at_value)) here ???
@start_time = time_attr_from_datetime(start_at)
end

def end_at=(end_at_value)
write_attribute(:end_at, end_at_value) # Maybe you need to do write_attribute(:end_at, DateTime.parse(end_at_value)) here ???
@end_time = time_attr_from_datetime(end_at)
end

private
def set_start_at
self.start_at = DateTime.parse("#{event_date} #{start_time}:00")
end

def set_end_at
self.end_at = DateTime.parse("#{event_date} #{end_time}:00")
end

def time_attr_from_datetime(datetime)
"#{'%02d' % datetime.hour}:#{'%02d' % datetime.min}"
end
end

编辑:获取和设置 start_time 和 end_time 有一个明确的模式。它可以通过元编程进行一些抽象,但我认为这会使示例变得不清楚。

关于ruby-on-rails - 在 Rails 模型中设置和获取虚拟属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12080868/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com