We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Saving relations with a lowercase alias don't work

After hours of trying to figure out why my relations are not stored, I came across this very old thread:

Since I recently ran into a similar problem I found this thread. My setup is:

  • phalcon 1.3.1
  • apache 2.2.26
  • php 5.5.13
  • OS X Mavericks

Here's what I found experimenting with this. Lower case aliases ('artists', 'songs') don't seem to work whereas upper case aliases ('Artists', 'Songs') do.

To add one element this worked:

$this->Elements = $element;

To add multiple elements this worked:

$elements = array($element1, $element2);
$this->Elements = $elements;

After that I had to save the object before accessing the elements again. When I didn't, phalcon would just return a result set with only the elements already in the database.

Am I doing something seriously wrong or what?

This still (or again) seems to be the case in 3.4.0. Is this by design or a bug?



8.4k
edited Mar '19

actually in Phalcon\Mvc\Model::__get() it converts the requested alias to lowercase and checks with model manager for the relation and if there is a relation it would check for existing property

Source code:

public function __get(string! property)
    {
        var modelName, manager, lowerProperty, relation, result, method;

        let modelName = get_class(this),
            manager = this->getModelsManager(),
            lowerProperty = strtolower(property);

        /**
         * Check if the property is a relationship
         */
        let relation = <RelationInterface> manager->getRelationByAlias(modelName, lowerProperty);
        if typeof relation == "object" {

            /*
             Not fetch a relation if it is on CamelCase
             */
            if isset this->{lowerProperty} && typeof this->{lowerProperty} == "object" {
                return this->{lowerProperty};
            }
            /**
             * Get the related records
             */
            let result = call_user_func_array(
                [manager, "getRelationRecords"],
                [relation, null, this, null]
            );

            /**
             * Assign the result to the object
             */
            if typeof result == "object" {

                /**
                 * We assign the result to the instance avoiding future queries
                 */
                let this->{lowerProperty} = result;

                /**
                 * For belongs-to relations we store the object in the related bag
                 */
                if result instanceof ModelInterface {
                    let this->_related[lowerProperty] = result;
                }
            }

            return result;
        }

        /**
         * Check if the property has getters
         */
        let method = "get" . camelize(property);

        if method_exists(this, method) {
            return this->{method}();
        }

        /**
         * A notice is shown if the property is not defined and it isn't a relationship
         */
        trigger_error("Access to undefined property " . modelName . "::" . property);
        return null;
    }
            ...


2.5k

I created a simple test to reproduce the issue, and created a bug report: https://github.com/phalcon/cphalcon/issues/13938