开发者

Two models with shared methods and same table? [CakePHP]

开发者 https://www.devze.com 2023-03-10 10:52 出处:网络
I currently have two models: Product and Servi开发者_StackOverflow社区ce. Both share the same table structure and the same methods. However, when I update one method, I\'ll have to do the same with th

I currently have two models: Product and Servi开发者_StackOverflow社区ce. Both share the same table structure and the same methods. However, when I update one method, I'll have to do the same with the other model. And it gets messy, not to mention I'm causing redundancy and it's not the best practice available.

I know the models can be linked to the same table, so I'll just have to add a $useTable = 'stuff' in the model and I could add a type field. However, I can't figure out how to create a "parent" model since each model extends the AppModel.

To be fair, I know almost next to nothing about OOP, so I could be missing something very obvious and simple.

What I would do without knowing how to extend two children (Product and Service) to a parent (Stuff) would be something like:

$this->Stuff->type = 'product';
$products = $this->Stuff->findAvailable();

But I bet there's a much simpler, cleaner approach.

Thanks.


Use a Behavior. As stated in the cookbook:

Model behaviors are a way to organize some of the functionality defined in CakePHP models. They allow us to separate logic that may not be directly related to a model, but needs to be there. By providing a simple yet powerful way to extend models, behaviors allow us to attach functionality to models by defining a simple class variable. That's how behaviors allow models to get rid of all the extra weight that might not be part of the business contract they are modeling, or that is also needed in different models and can then be extrapolated.

http://book.cakephp.org/view/1071/Behaviors

The link should give you a pretty good idea of where to start.


You're basically using Inheritability and Extendability:

Extendable: [link removed to comply with my noobie status. It is in the file below from gitub]

Inheritable: http://bakery.cakephp.org/articles/taylor.luk/2008/10/22/inheritable-behavior-missing-link-of-cake-model

Which were incorporated into: https://github.com/CakeDC/utils/blob/master/models/behaviors/inheritable.php

I just used this same method (also for products and services). Actually, I have different fields for each, common fields, and then sub-types (2 classes of products and 3 classes of services) so I created the Offer model with an offers table that looks like this:

CREATE TABLE `offers` (
  `id` int(11) NOT NULL AUTO_INCREMENT,    //common
  `carrier_id` int(11) DEFAULT NULL,       //common
  `category_id` int(11) DEFAULT NULL,      //common
  `name` varchar(255) DEFAULT NULL,        //common
  `description` longtext,                  //common
  `type` ENUM('Product', 'Service') not null default 'Product',
  `sku` varchar(255) DEFAULT NULL,         //product
  `make` varchar(255) DEFAULT NULL,        //product
  `model` varchar(255) DEFAULT NULL,       //product
  `listprice` decimal(9,2) DEFAULT NULL,   //product
  `soc_code` varchar(255) DEFAULT NULL,    //service
  `unit` varchar(255) DEFAULT NULL,        //service
  `units` int(11) DEFAULT NULL,            //service
  `mrc` decimal(9,2) DEFAULT NULL,         //service
  `created` datetime DEFAULT NULL,
  `modified` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `carrier_id` (`carrier_id`),
  KEY `category_id` (`category_id`),
  KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;       

Then my Offer model looks like this:

<?php
class Offer extends AppModel {
  public $name = 'Offer';
  public $useTable = 'offers';
  public $displayField = 'name';

  public $belongsTo = array(
    'Carrier' => array(
      'className' => 'Carrier',
      'foreignKey' => 'carrier_id',
    ),
    'Category' => array(
      'className' => 'Category',
      'foreignKey' => 'category_id',
    )
  );    

With the Product model:

<?php
App::import('Model', 'Offer');
class Product extends Offer {
  public $name = 'Product';
  public $useTable = 'offers';
  public $displayField = 'name';
  public $actsAs = array('utils.inheritable');

(Service is practically identical).

Then you create all of your methods within the Offer model and only anything uniquely suited to the subclasses products or services would exist in those models.

I hope this helps out if you haven't already found a solution.


Put the methods that both models share to your AppModel:

This intermediate class, AppModel, is empty and if you haven't created your own is taken from within the /cake/ folder. Overriding the AppModel allows you to define functionality that should be made available to all models within your application. To do so, you need to create your own app_model.php file that resides in the root of the /app/ folder.

Your Product and Service models extends AppModel. That means that all methods from AppModel are available for them.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号