0

I using zf2's tableGateway and I'm unsure of the design it leads to.

Here is the canonical example of how to use zf2's tableGateway to do an insert (this from the docs):

public function saveAlbum(Album $album)
    {
        $data = array(
            'artist' => $album->artist,
            'title'  => $album->title,
        );

        $id = (int)$album->id;
        if ($id == 0) {
            $this->tableGateway->insert($data);
        } else {
            if ($this->getAlbum($id)) {
                $this->tableGateway->update($data, array('id' => $id));
            } else {
                throw new \Exception('Form id does not exist');
            }
        }
    }

But defining the $data array seems redundant because I already have an Album class that looks like this:

class Album
{
    public $id;
    public $artist;
    public $title;

    public function exchangeArray($data)
    {
        $this->id     = (isset($data['id'])) ? $data['id'] : null;
        $this->artist = (isset($data['artist'])) ? $data['artist'] : null;
        $this->title  = (isset($data['title'])) ? $data['title'] : null;
    }
}

In my own project I have a model with about 25 properties (a table with 25 columns). It seems redundant to have to define the class with 25 properties and than also write a $data array inside of the method of a class implementing tableGateway with an element for every one of those properites. Am I missing something?

tereško
  • 58,060
  • 25
  • 98
  • 150
red888
  • 27,709
  • 55
  • 204
  • 392

2 Answers2

2

Another way is to use RowGateway http://framework.zend.com/manual/2.3/en/modules/zend.db.row-gateway.html

Briefly, I'd extend album class from \Zend\Db\RowGateway\AbstractRowGateway class.

<?php
namespace Module\Model;

use Zend\Db\RowGateway\AbstractRowGateway;
use Zend\Db\Adapter\Adapter;
use Zend\Db\Sql\Sql;

class Album extends AbstractRowGateway
{
    protected $primaryKeyColumn = array( 'id' );
    protected $table = 'album';


    public function __construct( Adapter $adapter )
    {
        $this->sql = new Sql( $adapter, $this->table );
        $this->initialize();
    }

}

And then you can do like this

$album->title = "Some title";
$album->save();

Or

$album->populate( $dataArray )->save();
Roman
  • 51
  • 2
1

You may want to take a look at my QuickStart 101 Tutorial.

Basically you could do:

saveAlbum(Album $albumObject) 
{
    $hydrator   = new ClassMethods(false);
    $albumArray = $hydrator->extract($albumObject);
    // v-- not too sure if that one-liner works; normal if() in case it doesn't
    isset($albumArray['id']) ? unset($albumArray['id']) :; 

    // insert into tablegateway
}
Sam
  • 16,435
  • 6
  • 55
  • 89
  • Heyyy that's nifty. I don't understand the last line though, why are you doing: isset($albumArray['id']) ? unset($albumArray['id']) :; – red888 Apr 23 '14 at 20:14
  • well, the ID field shouldn't be existant on the DATA to update or insert (since it's usually autoID). Therefore you remove it only when it's existing, which on a new object is not the case but for an edit-object it is. – Sam Apr 24 '14 at 07:12