realm / realm-swift

Realm is a mobile database: a replacement for Core Data & SQLite
https://realm.io
Apache License 2.0
16.32k stars 2.15k forks source link

Default values for ignored properties don't work with query results #4356

Closed stevenp closed 3 years ago

stevenp commented 7 years ago

Goals

I'm trying to have ignored properties on my models that have default values set.

Expected Results

If I create a property on a model that has a default value:

 var testIgnoredProperty: String = "x"

...I want to be able to access the default value on both newly instantiated models and models retrieved from the database.

Actual Results

When I create a new model instance with a default value set for an ignored property, I can access that property's value in a new instance, but when I retrieve the same model from the database, the default value is not set for the query result.

Steps to Reproduce

This is the test model class:

class IgnoredPropertyTest: RLMObject {

    dynamic var id: String = ""

    dynamic var testIgnoredProperty: String = "x"

    override public class func primaryKey() -> String? {
        return "id"
    }

    override public class func ignoredProperties() -> [String]? {
        return ["testIgnoredProperty"]
    }
}

This is how I'm reproducing the behavior:

let realm = RLMRealm.default()
realm.beginWriteTransaction()

let test = IgnoredPropertyTest()
test.id = "1"
print(test.testIgnoredProperty) // prints "x"

realm.addOrUpdate(test)

try realm.commitWriteTransaction()

let testFetched = IgnoredPropertyTest(forPrimaryKey: "1")!
print(testFetched.testIgnoredProperty) // prints ""

I would expect to see x printed twice, but in the case of the model retrieved from the database, the default value that's assigned to this property is gone. I've scoured the documentation and other issues to see if there's something obvious I'm missing here, but I can't figure it out. Is this the expected behavior? If so, is there a way to work around this?

Version of Realm and Tooling

Realm version: 2.1.0

Xcode version: 8.1

iOS/OSX version: 10.1/10.12.2

Dependency manager + version: Cocoapods 1.2.0.beta.1

stevenp commented 7 years ago

This seems to occur for lazy properties as well. Everything I've read seems to indicate that ignored lazy properties are supposed to work as expected in Realm.

stevenp commented 7 years ago

It appears that this is either a bug or a limitation. I modified SwiftPropertyTypeTest.swift to test this behavior using the existing test case:

func testIgnoredLazyVarProperties() {
    let realm = realmWithTestPath()

    let succeeded : Void? = try? realm.transaction {
        let object = SwiftIgnoredLazyVarObject()
        realm.add(object)
        XCTAssertEqual(object.ignoredVar, "hello world")
    }

    XCTAssertNotNil(succeeded, "Writing an object with an ignored lazy property should work.")

    let fetchedObjects = SwiftIgnoredLazyVarObject.allObjects(in: realm)
    if let fetchedObject = fetchedObjects.firstObject() as? SwiftIgnoredLazyVarObject {
        XCTAssertEqual(fetchedObject.ignoredVar, "hello world")
    } else {
        XCTFail("Unable to retrieve saved SwiftIgnoredLazyVarObject")
    }
}

The result:

SwiftPropertyTypeTest.swift:136: error: -[Tests.SwiftPropertyTypeTest testIgnoredLazyVarProperties] : 
XCTAssertEqual failed: ("") is not equal to ("hello world") - 
Test Case '-[Tests.SwiftPropertyTypeTest testIgnoredLazyVarProperties]' failed (0.081 seconds).
Test Suite 'SwiftPropertyTypeTest' failed at 2016-11-22 13:48:26.250.
     Executed 1 test, with 1 failure (0 unexpected) in 0.081 (0.198) seconds

As you can see, the lazy property doesn't function as expected on a model from a query result. Is it safe to say that lazy properties just aren't supported in realm-cocoa at the moment?

austinzheng commented 7 years ago

Thanks for getting in touch with us. What happens if you remove the dynamic modifier from the ignored property (testIgnoredProperty)?

stevenp commented 7 years ago

Removing the dynamic modifier has no effect. I've tried this both in my sample, and in SwiftIgnoredLazyVarObject in the Realm test cases as well.

austinzheng commented 7 years ago

This does seem like a bug, or at least an oversight. Thanks for bringing it to our attention, we'll add it to our backlog.

stevenp commented 7 years ago

Thanks for the quick reply, @austinzheng! I may look into it some more to see if I can figure out what's going on.