yii2 icon indicating copy to clipboard operation
yii2 copied to clipboard

17071 fix BaseActiveRecord::populateRecord() method

Open np25071984 opened this issue 7 years ago • 10 comments

Q A
Is bugfix? yes
New feature? no
Breaks BC? no
Tests pass? yes
Fixed issues #17071, #15265

np25071984 avatar Jan 27 '19 16:01 np25071984

This will break getDirtyAttributes() and isAttributeChanged() behavior - === will return false if you compare 2 cloned object (even if they're identical).

rob006 avatar Jan 27 '19 18:01 rob006

This will break getDirtyAttributes() and isAttributeChanged() behavior - === will return false if you compare 2 cloned object (even if they're identical).

I think we should introduce isEqual method, which compares two values and returns boolean. If the method obtain objects, it will compare them member by member.

np25071984 avatar Jan 27 '19 19:01 np25071984

I think we should introduce isEqual method

Related: #5375

rob006 avatar Jan 27 '19 19:01 rob006

Maybe we should keep isEqual method somewhere in Helper? It can be useful in many cases! And do we really need * identical values using `===`, defaults to `true`. Otherwise `==` is used for comparison.

np25071984 avatar Jan 27 '19 19:01 np25071984

I decided to get rid of identical parameter in isAttributeChanged method. Possibly, it isn't a good decision, but I didn't find usage this parameter within whole the source.

np25071984 avatar Jan 27 '19 21:01 np25071984

I don't like this isEqual() method. It looks over-complicated and bugged (Expression may hold params, which are ignored on casting to string). All we need is to compare object properties (probably recursively) using strict comparison, there is no need to special treatment for expressions.

rob006 avatar Jan 27 '19 21:01 rob006

Manual tells us

When using the comparison operator (==), object variables are compared in a simple manner, namely: Two object instances are equal if they have the same attributes and values (values are compared with ==), and are instances of the same class

Why don't we compare them by native method '$obj1 == $obj2'?

np25071984 avatar Jan 27 '19 21:01 np25071984

Because it will use == also for comparing properties, while we need to use === in this case.

rob006 avatar Jan 27 '19 21:01 rob006

@rob006 , would you like to comment the current statue? Also, I need a clue to deal with Cognitive Complexity.

np25071984 avatar Jan 28 '19 10:01 np25071984

I was thinking about something like:

public function isAttributeChanged($name, $identical = true) {
    if (isset($this->_attributes[$name], $this->_oldAttributes[$name])) {
        if ($identical) {
            if (is_object($this->_attributes[$name]) && is_object($this->_oldAttributes[$name])) {
                return !(
                    $this->_attributes[$name] == $this->_oldAttributes[$name]
                    && (array) $this->_attributes[$name] === (array) $this->_oldAttributes[$name]
                );
            }
            return $this->_attributes[$name] !== $this->_oldAttributes[$name];
        }
        return $this->_attributes[$name] != $this->_oldAttributes[$name];
    }
    return isset($this->_attributes[$name]) || isset($this->_oldAttributes[$name]);
}

rob006 avatar Jan 28 '19 19:01 rob006