我有下表:
event_id value created_at updated_at
1 15.2 2014/01/01 00:00 2014/01/01 00:00
2 15.5 2014/01/01 00:10 2014/01/01 00:10
3 15.9 2014/01/01 00:20 2014/01/01 00:20
但是,如果新事件的值与之前的事件(在最新的事件中)相同,则上一个事件应将“updated_at”设置为当前时间,并且不应创建新事件。
在上面的示例中,如果我执行Event.new(:value => 15.9),那么ID为3的事件应将updated_at设置为当前时间 - 这应该是唯一的更改。
有关如何完成此任务的任何建议?我试图摆弄Active Record回调,但在中止创建时失败(使用回滚)。当然可以使用特殊的“构造函数”方法来解决,但我想避免这种情况。
答案 0 :(得分:4)
Event.where(value: params[:value]).first_or_create.touch
或在event.rb
before_save :update_if_existing
private
def update_if_existing
if event = Event.find_by(value: value)
event.touch # updates the updated_at timestamp if the existing event
false # prevents the current event from being inserted into the db
end
end
答案 1 :(得分:1)
你可以这样做,让我们说@event
是对象,在保存之前你要检查值
unless @event.value == Event.last.value
@event.save
else
Event.last.update_attributes(:updated_at => DateTime.now)
end
或者您可以使用三元运算符
在一行中完成此操作(@event.value == Event.last.value) ? (Event.last.update_attributes(:updated_at => DateTime.now)) : (@event.save)
答案 2 :(得分:1)
Event.find_or_create_by_value(params[:value]).touch
此方法将按值查找事件,或者如果此值不存在,则创建一个事件。 Touch方法将更新此记录的updated_at
时间戳。
答案 3 :(得分:0)
由于您对Event的定义是没有两个事件应该具有相同的value
- 您应该在该字段上添加唯一索引,这也将使任何此类操作更快。
实际上,由于您的活动未由id
定义,而是由其value
定义,请考虑将其primary key更改为value
:
create_table(:event, :primary_key => 'value') do |t|
t.column :userID, :decimal, :null => false
...
end
class Event
set_primary_key :value
...
end
现在你可以做到:
Event.find_or_create_by_value(params[:value]).touch