Laravel Model Macroable use a macro to add the ability to model data

What is ThinkSNS?
ThinkSNS (referred to as TS), a fully integrated platform for the social system, the provision of social software development and technical solutions for domestic and foreign medium and small enterprises and entrepreneurs.

Generate demand
when using Laravel development ThinkSNS Plus, as many functional blocks are not written in a library inside, add the actual function of the form to expand the use of the package, which is also used in many parts of the relationship "polymorphic many to many" of. The question is, develop a quiz program, wants to increase user model or answer questions posted relations, initially inherited a User model, adding a relationship, after you see the problem, because the user is using the tag Polymorphism to-many relationship, my model is derived by the user is unable to get this relationship because *** able_type data is user data model class name or an alias. And then I will change the inherited class.

Complete the requirements
will think that there is a Trait called the Macroable in Laravel and then found Builder have this capability, but there is no Model, will also be added to this Trait on the model you want to use, and later found that if other models also use You are not have to add one? Subsequently wrote a Trait:

trait Macroable
{
    use \Illuminate\Support\Traits\Macroable {
        __call as macroCall;
    }

    /**
     * Get a relationship value from a method.
     *
     * @param string $key
     * @return mixed
     * @author Seven Du <[email protected]>
     */
    public function getRelationValue($key)
    {
        $relation = parent::getRelationValue($key);
        if (! $relation && static::hasMacro($key)) {
            return $this->getRelationshipFromMethod($key);
        }

        return $relation;
    }

    /**
     * Handle dynamic method calls into the model.
     *
     * @param string $method
     * @param array $parameters
     * @return mixed
     * @author Seven Du <[email protected]>
     */
    public function __call($method, $parameters)
    {
        if (static::hasMacro($method)) {
            return $this->macroCall($method, $parameters);
        }

        return parent::__call($method, $parameters);
    }

    /**
     * Handle dynamic static method calls into the method.
     *
     * @param  string  $method
     * @param  array  $parameters
     * @return mixed
     */
    public static function __callStatic($method, $parameters)
    {
        return parent::__callStatic($method, $parameters);
    }
}

As long as the model to be used can be in use.

Use
With this Trait then we added to the User model, you can use a macro for its ability to dynamically add a function:

User::macro('questions', function () {
    return $this->hasMany(Question::class, 'user_id', 'id');
});

In this way, we can directly:

$questions = $user->questions;

Get all the questions posted by users.

The code above are from ThinkSNS Plus, look at the full development code can be seen Warehouse:

GitHub: https://github.com/slimkit/thinksns-plus (Open source is not easy, seeking Star)

Guess you like

Origin blog.51cto.com/14231620/2416306