Skip to content
Draft
3 changes: 1 addition & 2 deletions lib/couchbase-orm/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ module CouchbaseOrm
class Document
include Inspectable
include ::ActiveModel::Model
include ::ActiveModel::Dirty
include Changeable # override some methods from ActiveModel::Dirty (keep it included after)
include Changeable
include ::ActiveModel::Attributes
include ::ActiveModel::Serializers::JSON

Expand Down
1 change: 0 additions & 1 deletion lib/couchbase-orm/changeable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ def move_changes

def changes_applied
move_changes
super
end

def reset_object!
Expand Down
8 changes: 4 additions & 4 deletions lib/couchbase-orm/types/timestamp.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ module Types
class Timestamp < ActiveModel::Type::DateTime
def cast(value)
return nil if value.nil?
return Time.at(value) if value.is_a?(Integer) || value.is_a?(Float)
return Time.at(value.to_i) if value.is_a?(String) && value =~ /^[0-9]+$/
return value.utc if value.is_a?(Time)
super(value).utc
return Time.at(value).floor if value.is_a?(Integer) || value.is_a?(Float)
return Time.at(value.to_i).floor if value.is_a?(String) && value =~ /^[0-9]+$/
return value.utc.floor if value.is_a?(Time)
super(value).utc.floor
Comment on lines +6 to +9
Copy link
Preview

Copilot AI Aug 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The addition of .floor calls changes the behavior of timestamp casting by truncating subsecond precision. This could be a breaking change for consumers expecting microsecond precision in timestamps. Consider documenting this behavioral change or making it configurable.

Suggested change
return Time.at(value).floor if value.is_a?(Integer) || value.is_a?(Float)
return Time.at(value.to_i).floor if value.is_a?(String) && value =~ /^[0-9]+$/
return value.utc.floor if value.is_a?(Time)
super(value).utc.floor
return Time.at(value) if value.is_a?(Integer) || value.is_a?(Float)
return Time.at(value.to_i) if value.is_a?(String) && value =~ /^[0-9]+$/
return value.utc if value.is_a?(Time)
super(value).utc

Copilot uses AI. Check for mistakes.

end

def serialize(value)
Expand Down
2 changes: 1 addition & 1 deletion lib/couchbase-orm/utilities/query_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ def build_not_match(key, value)
end

def serialize_value(key, value_before_type_cast)
value =
value =
if value_before_type_cast.is_a?(Array)
value_before_type_cast.map do |v|
attribute_types[key.to_s].serialize(attribute_types[key.to_s].cast(v))
Expand Down
9 changes: 8 additions & 1 deletion spec/type_nested_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ class TypeNestedTest < CouchbaseOrm::Base
obj.others[1].child = SubTypeTest.new(name: "baz")
obj.save!

expect(obj.others[0].name).to eq "foo"
expect(obj.others[0].tags).to eq ["foo", "bar"]
expect(obj.others[1].name).to eq "bar"
expect(obj.others[1].tags).to eq ["bar", "baz"]
expect(obj.others[1].child.name).to eq "baz"

obj = TypeNestedTest.find(obj.id)
expect(obj.others[0].name).to eq "foo"
expect(obj.others[0].tags).to eq ["foo", "bar"]
Expand Down Expand Up @@ -116,7 +122,8 @@ class TypeNestedTest < CouchbaseOrm::Base
obj.others[1].name = "baz"
obj.flags[0] = true

obj.save!
expect { obj.save! }.to_not change { [obj.main.name, obj.others[0].name, obj.others[1].name, obj.flags] }

obj = TypeNestedTest.find(obj.id)
expect(obj.main.name).to eq "bar"
expect(obj.others[0].name).to eq "bar"
Expand Down
5 changes: 5 additions & 0 deletions spec/type_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
require "couchbase-orm/types"

class DateTimeWith3Decimal < CouchbaseOrm::Types::DateTime
def cast(value)
result = super(value)
result&.floor(3)
end

def serialize(value)
value&.iso8601(3)
end
Expand Down