Display Admin Grid For One Controller On A Related Records View, And Db Schema Question

I’ve only used Yii for a very simple web interface before, and now I’m trying to write something that’s much more complex, though I’ll give a simple example of my issue.


DB Schema (simplified):

CREATE TABLE IF NOT EXISTS `ticket` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `name` varchar(50) NOT NULL,

  `title` varchar(50) NOT NULL,

  `manager` varchar(50) NOT NULL,

  `request` text NOT NULL,

  PRIMARY KEY (`id`)

) ENGINE=InnoDB  DEFAULT CHARSET=utf8;


CREATE TABLE IF NOT EXISTS `equipment` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `ticket_id` int(11) NOT NULL COMMENT 'CONSTRAINT FOREIGN KEY (ticket_id) REFERENCES Ticket(id)',

  `name` varchar(25) NOT NULL,

  `description` varchar(30) NOT NULL,

  PRIMARY KEY (`id`)

) ENGINE=InnoDB  DEFAULT CHARSET=utf8;



Essentially, this is for a system to track requests for hardware. A single request ticket can have multiple pieces of hardware that are requested by that ticket…

The workflow would be a request email comes in, a Ticket gets created with details about who the request is for, their request, etc. Once that ticket has been created, I want the user to end up on the View screen for that Ticket, but have below the ticket detail, an admin grid for the Equipment that’s associated with that ticket Id.

Inside my TicketController, I’ve written code which will perform a renderPartial against //equipment/_admin (and I’ve created a simple _admin.php which draws the Grid for Equipment where the ticket_id field matches the shown Ticket’s ID. I’m passing that renderPartial as text to the render for the Ticket view as another parameter (beyond the Ticket $model). That looks like I want it to, but all the action icons in the grid think the Controller they should act on is the Ticket controller, when it should actually go against the Equipment Controller.

I’ve tried to figure some way to override the Controller for the Grid widget, but I didn’t see a way to do that.

I’ve read some posts replying to people with similar questions that suggested creating a widget out of it, and just call the widget. That doesn’t really help me figure out how to do what I’m trying to do though… Other posts have suggested calling the second controller (Equipment, in my case) directly via Ajax. That sounds very promising, but the only way I’ve see in Yii to have Ajax calls is with links or buttons. I want the page to load up, show the ticket view, and show the admin grid for equipment (filtered for that ticket) below it. Doing it with Ajax would work, I think, if it could automatically load it when the page comes up, without having to click another link or button.

On another note, is this a bad database design??? From a database perspective, I can see how we’d end up with two tickets for the same user, requesting two different pieces of equipment, but then I feel certain that later someone would want to run a report to show what equipment is assigned to which person… It seems like I should have a “User” table too, so multiple tickets don’t make reports look like there are two "Joe Smith"s, each with one piece of equipment. I mean, technically, one ticket could potentially request hardware for multiple people… Any suggestions on this front?

you can override the urls for the buttons in the grid


array(

			'class'=>'CButtonColumn',

			'viewButtonUrl' => '["equipment/view", "id" => $data->id]',

			'updateButtonUrl' => '["equipment/update", "id" => $data->id]',

			'deleteButtonUrl' => '["equipment/delete", "id" => $data->id]',

		)

Hello Taige,

You can try alirz23 way so you don’t need to change anything, Just an idea, I would let the equipment controller render the equipment admin for the ticket pk (id) in your ticket generation action, just send the ecrypted ticket it to the


$this->redirect(array('EquipmentController/admin', 'ticketId' => encrypt($model->id)));

and if you want to show the ticket details since you’ve ticket id, you you can have a ticket detail view in equipment admin page in your equipemt folder. you can load the $ticket = ticket_model::findByPk(ticket_id), and pass it to cdetail view from controller.

sample equipment controller acionAdmin




    public function actionAdmin() {

        $ticketId = null;

        if(isset($_GET["ticketId"])){

          $ticketId = decrypt($_GET["ticketId"]); //Yii::app()->getRequest()->getQuery('ticketId'); if you want

        }

        $ticketModel = Ticket::model()::findByPk($ticketId);

        $model = new Equipment('search');

        $model->unsetAttributes();  // clear any default values

        if (isset($_GET['Equipment']))

            $model->attributes = $_GET['Equipment'];


        $this->render('admin', array(

            'model' => $model, "ticketModel"=>$ticketModel

        ));

    }



in equipment model search function




$criteria = new CDbCriteria;

        $ticketId = null;

        if(isset($_GET["ticketId"])){

          $ticketId = decrypt($_GET["ticketId"]); //Yii::app()->getRequest()->getQuery('ticketId'); if you want

        }

        $criteria->compare('ticket_id', $ticketId); //ticket_id equipment table foreign key

             



in equipment admin view




//cdetail view taken from ticket

$this->widget('zii.widgets.CDetailView', array(

	'data'=>$ticketModel,

	'attributes'=>array());

under equipment cgrid view 

$this->widget('zii.widgets.grid.CGridView', array(

    'id' => 'equip,ent-grid',

    'dataProvider' => $model->search(),

     'columns' => array()));




later you can view the tickects requested by user for that view function you can anytime redirect to this equipment action admin, hope this helps you.

Thanks to both of you! Both of these suggestions look workable. I looked for a way to do this for hours yesterday, so thank you very much…

At this point, I’ve gone with the 1st suggestion and it’s working well. I see the advantage to the 2nd method, but I need to also show another set of data on this same page.