Choosing between Symfony's Doctrine ORM files Model.class.php and ModelTable.class.php
Asked Answered
F

3

0

when doctrine builds model files for a table, it generates three files, essentially BaseModel.class.php, Model.class.php and ModelTable.class.php. Common knowledge requires that any modifications be done to Model.class.php or ModelTable.class.php vs BaseModel.class.php.

But when do you choose between either Model.class.php vs ModelTable.class.php. From what I gather is that Model.class.php is for a single instance and ModelTable.class.php is for multiple instances.

Can anyone shed any light here?

Forepart answered 30/7, 2012 at 1:16 Comment(0)
F
2

it's so simple!

suppose you have a Model Called Article. you will have three classes called BaseArticle.class.php and Article.class.php and ArticleTable.class.php

here is the definition for each class:

BaseArticle.class.php : this class has your model definition(or your table definition). you don't want to edit this class Ever!

Article.class.php : is a place for your override methods that you can write for your models. you only have access to these functions when you have an instance of Article Class. so you can call them only by an object. for example:

class Album extends BaseArticle {

    public function getSummary(){
         ....
    }

}

for using it you should do this:

$article=new Article();
$article->getSummary();

ArticleTable.class.php : and this is where you want to write your functions that are for your whole Article talbe(or it's better to say for your whole Article model). for examlpe you want to find most popular articles, you can't write this function to your Article Class because it works only on an object. but you want to do this on your whole Table. so:

class AlbumTable extends Doctrine_Table {
    public static function getPopularArticles() {
    }
}

and you have to use it like this if your functions are static:

ArticleTable::getPopularArticles();

and if your functions are not static you can call them using:

Doctrine_Core::getTable('Product')->your_nonstatic_function();
Finnigan answered 1/8, 2012 at 16:26 Comment(6)
also why do you say ArticleTable functions/methods must be static? I do have a couple of methods in here that are not static but work fine.Forepart
because you want to call those functions without Instantiation and in this case your functions should be static. otherwise you can's access them using ArticleTable::getXXX()Finnigan
Firouziam, You are confusing an instance of the ArticleTable with an instance of Article. Many (if not most) uses of Table methods are not static. To call non-static Table methods you should use the code I included in my answer: Doctrine_Core::getTable('Product') This will retrieve an instance of the table class to allow calls to non-static functions.Lykins
@Lykins yeah you're right. Table Functions can be non static (and i will edit my answer) but i'm not confusing ArticleTable Class with Article. i just find it useless to use non static functions in this class. when you can access them with class name. but you're right using Doctrine_Core::getTable('Article') you can call non static functions in ArticleTable. thanks for the notice.Finnigan
@Finnigan What I said about 'You are confusing an instance of the ArticleTable with an instance of Article' was referring to your (since edited) explanation of why ArticleTable methods should be static.Lykins
@Firouziam, Also, I disagree with you about the propriety of using static methods in the ArticleTable class. All the pre-built Table functions in the Doctrine_Table class are non-static. If you make static functions, you can't use any of these powerful methods. Additionally, the constructor method for Table classes is important for making sure connections get properly Intialized for the table and that filters and other resources get loaded. Static methods will work in most cases but I do not believe this is good Symfony design (especially just to save a little typing).Lykins
L
3

J0k's answer is informative but doesn't really answer the question in layman's terms. ESP. regarding the single vs. multiple questions.

The difference is not really single vs. multiple instances, but more one of instantiated vs. uninstantiated.

Very Simply:

You use the Table functions when you don't yet have an instance of the object you want to read or manipulate.

You use the Class functions when you already have an instance of the object and you want to save it, update it, or retrieve more information(related objects) about it.

Often Table functions are accessed from Class functions

More Complexly:

Often, with good design, you will need to create methods in both the regular Class methods and the Table methods.

Say you have a Customer with a one to many relationship to Purchases (which has a one to many relationship to Products)

Say you want to write a method or getting all of a Customer's Products.

in Customer.class.php you create a:

public function getProducts(){}

you create this in the regular class, because you'll only be interested in a what products a customer has once you have your customer

this might call something like:

Doctrine_Core::getTable('Product')->getByCustomerId($this->get('id')

Here, you may not have any Product instances yet, but you want to retrieve them, so this should go in the Table class.

The reason why this doesn't simply break down into Single vs. Multiple is: if you were to make a function that refunds all Products belonging to a Customer. You might be dealing with Multiple Products, but you wouldn't want to create your functionality just in the table. You may need to make an API call to your payment processor, you may need to check the refund period on each products, ETC.

Instead, you create Table Functions to retrieve the right data, and then manipulate that data by creating Class Functions.

Note that I see good programmers get this 'wrong' all the time. This often comes down to a matter of individual style.

Lykins answered 30/7, 2012 at 21:35 Comment(0)
F
2

it's so simple!

suppose you have a Model Called Article. you will have three classes called BaseArticle.class.php and Article.class.php and ArticleTable.class.php

here is the definition for each class:

BaseArticle.class.php : this class has your model definition(or your table definition). you don't want to edit this class Ever!

Article.class.php : is a place for your override methods that you can write for your models. you only have access to these functions when you have an instance of Article Class. so you can call them only by an object. for example:

class Album extends BaseArticle {

    public function getSummary(){
         ....
    }

}

for using it you should do this:

$article=new Article();
$article->getSummary();

ArticleTable.class.php : and this is where you want to write your functions that are for your whole Article talbe(or it's better to say for your whole Article model). for examlpe you want to find most popular articles, you can't write this function to your Article Class because it works only on an object. but you want to do this on your whole Table. so:

class AlbumTable extends Doctrine_Table {
    public static function getPopularArticles() {
    }
}

and you have to use it like this if your functions are static:

ArticleTable::getPopularArticles();

and if your functions are not static you can call them using:

Doctrine_Core::getTable('Product')->your_nonstatic_function();
Finnigan answered 1/8, 2012 at 16:26 Comment(6)
also why do you say ArticleTable functions/methods must be static? I do have a couple of methods in here that are not static but work fine.Forepart
because you want to call those functions without Instantiation and in this case your functions should be static. otherwise you can's access them using ArticleTable::getXXX()Finnigan
Firouziam, You are confusing an instance of the ArticleTable with an instance of Article. Many (if not most) uses of Table methods are not static. To call non-static Table methods you should use the code I included in my answer: Doctrine_Core::getTable('Product') This will retrieve an instance of the table class to allow calls to non-static functions.Lykins
@Lykins yeah you're right. Table Functions can be non static (and i will edit my answer) but i'm not confusing ArticleTable Class with Article. i just find it useless to use non static functions in this class. when you can access them with class name. but you're right using Doctrine_Core::getTable('Article') you can call non static functions in ArticleTable. thanks for the notice.Finnigan
@Finnigan What I said about 'You are confusing an instance of the ArticleTable with an instance of Article' was referring to your (since edited) explanation of why ArticleTable methods should be static.Lykins
@Firouziam, Also, I disagree with you about the propriety of using static methods in the ArticleTable class. All the pre-built Table functions in the Doctrine_Table class are non-static. If you make static functions, you can't use any of these powerful methods. Additionally, the constructor method for Table classes is important for making sure connections get properly Intialized for the table and that filters and other resources get loaded. Static methods will work in most cases but I do not believe this is good Symfony design (especially just to save a little typing).Lykins
S
0

You will find a very well answer in the official documentation, at Model Classes.

Basically, about Model.class.php:

Model is object classe that represent a record in the database. They give access to the columns of a record and to related records. This means that you will be able to know the title of an model by calling a method of an Model object.

For ModelTable.class.php:

ModelTable are table classe; that is, classe that contain public methods to operate on the tables. They provide a way to retrieve records from the tables. Their methods usually return an object or a collection of objects of the related object class

And BaseModel.class.php:

The Base classes kept in the lib/model/doctrine/base/ directory are the ones directly generated from the schema. You should never modify them, since every new build of the model will completely erase these files.

Sodom answered 30/7, 2012 at 9:10 Comment(1)
So essentially, when I want to retrieve columns of a single record, I will code them in the Model.class.php and when I want to retrieve multiple records, I will code them into ModelTable.class.php. Is this correct?Forepart

© 2022 - 2024 — McMap. All rights reserved.