Search code examples
phplaraveldoctrineeloquentpropel

Laravel (Eloquent) Table || Peer equivalent


Propel uses Peer classes, and doctrine used Table classes as a way to manipulate respective objects and object properties, without having to pollute the actual object with static methods.

After cursory glance of the laravel (eloquent) docs, I didn't see anything that eloquent provides for the same Peer or Table like functionality. My question is, does laravel (or eloquent) provide a namespace for such classes, or do I just use Table and let autoloader take care of the rest?

// Example use of a table class in doctrine 1.2
$user = UserTable::getInstance()->findById(1);

-- Update 1 --

Layman example of how a doctrine table class may be used:

class UserTable
{
    public static function getInstance()
    {
        return Doctrine_Core::getTable('User');
    }

    public function linkFoo($userId, array $foos)
    {
        $user = $this->findById($userId);

        foreach ($foos as $foo) {

            $user->foo = $foo;

            $user->save();
        }
    }
}

// SomeController.php
executeSaveFoo()
{
    UserTable::getInstance()->linkFoo($this->getUser(), array('foo1', 'foo2'));
}

The purpose of the doctrine table class is to provide an api for actions against respective objects which should not be in the controller, in the above example the linkFoo class will link provided foos to the respective user object.

I feel the separation between objects and 'table' classes is important, as an object shouldn't know how to instantiate nor hydrate itself.


Solution

  • As mentioned earlier, there is more than one way to accomplish the task, but here's a quick example using Commands.

    Controller

    namespace App\Http\Controllers;
    
    //...
    use App\Http\Requests\UpdateUserRequest;
    use App\Commands\UpdateUser;
    use App\User;
    //...
    
    class UserController extends Controller {
    
    /**
     * Update the specified resource in storage.
     *
     * @param  int  $id
     * @return Response
     */
    public function update(UpdateUserRequest $request, $id)
    {
        //gather request data
        $data = $request->all();
    
        //retrieve user
        $user= User::findOrFail($id);
    
        //update user
        $updateUser = \Bus::dispatch(
                            new UpdateUser($user, $data)
                         );
    
        //check if update was successful
        if($updateUser)
        {
            //update successful
            return redirect('/route/here')->with('message', 'User updated successfully');
        }
        else
        {
            //else redirect back with error message
            return redirect()->back()->with('error', 'Error updating user');
        } 
    }
    }
    

    The UpdateUserRequest class would handle validation.

    Command

    namespace App\Commands;
    
    use App\Commands\Command;
    
    use Illuminate\Contracts\Bus\SelfHandling;
    
    class UpdateUser extends Command implements SelfHandling {
    
        protected $user, $data;
    
        /**
         * Create a new command instance.
         */
        public function __construct($user, $data)
        {
            $this->user= $user;
            $this->data = $data;
        }
    
        /**
         * Execute the command.
         */
        public function handle()
        {
            //assign first name
            $this->user->first_name = $this->data['first_name'];
    
            //assign last name
            $this->user->last_name = $this->data['last_name'];
    
            //assign email address
            $this->user->email = $this->data['email'];
    
            //update user
            if($this->user->update())
            {
                //updated successfully, return true
                return true;
            }
            else
            {
                //else return false
                return false;
            } 
        }
    
    }