Codeigniter 2 models - php

I've to fetch data from different web services + my own database and combining these data before displaying in the site.
What's the best method for doing this? I prefer writing separate models for web services and database. How can I organize the model classes of different data sources in different folders?
I may add more webservices later.

EDIT: I am Really sorry, as my example below will not work, as you cannot have equally named models. You should prefix them in the subdirectories as well, like:
webservice1/ws1_products
webservice2/ws2_products
db/db_products
products
That way you will load them as
$this->load->model('webservice1/ws1_products');
$this->load->model('webservice2/ws2_products');
$this->load->model('db/db_products');
$this->load->model('products');
And use as
$x = $this->ws1_products->getAll();
$x = $this->ws2_products->getAll();
$x = $this->db_products->getAll();
$x = $this->products->getAll(); // combined result
End of edit.
To separate them in different folders simply put them in subfolders in models directory, then use common syntax $this->load->model('web_service1/products');.
I don't know the best method, as it is a matter of preference, but if I were you, I would separate them as you said in two different models and made a third one, that would combine them to one result.
So if you have to get products from 2 different services and your database, I would make 4 models:
webservice1/products
webservice2/products
db/products
products // the model that combines them to one result
That way you would have to make only one request from the controller, to the products model.

I usually do one model file per data source. Be it a DB table, web service, etc.
For combining data from 2 or more models before rendering I like to do it in the controller if there is business logic involved. If not I do it right in the model (you can now load one model from another in CI2)

Related

CakePHP - What is the best pratice for the Single Responsibility Principle?

I have a conceptual question, what is the best way to gather information from various models and treat them in different ways in order to return an array with the requested data, without using a "god" method?
I'll summarize the example I'm trying:
View "Payroll" is characterized by a html table that shows information of an employee, for example: base salary, every discount of the month (from the Payments table) as well as commissions from another table, so in Controller I just do $this->set($employee_info, $this->Employee->getInfo());
This method is responsible for gathering information from models that are not even related to him in some way (e.g.: Configuration Model) and at the end it returns the array required, the question is: what the best way to separate these responsibilities?
This method is responsible for gathering information from models that
are not even related to him in some way
You won't get around to call several models in this case in what you call a "god" method. The only way to get around that is to associate the data.
I would create three methods, one that fetches the data from all models, one that creates the data structure you want from that data and one that calls the two others and returns the data. I don't see a better way to separate that without having the data associated.

should I use one large sql query in model or break it up into smaller queries?

I'm using codeigniter for one of my projects, and right now what I have is a table with PROJECT information, and I'm displaying all the PROJECTS in a specific view.
Now, I also want that same view to display other related information about the projects such as the number of views as well as the associated tags. But this would require multiple JOINS in the model(which would require me to alter the existing query...) but it would keep the view from having to call the model directly.
Would I get better performance if I simply break up the queries, and have 2 separate queries related to the other information in the VIEW? I find this to be more clear, but I wonder if it's slower since I'm calling the model for EACH project in a loop.
Why dont you just code both - and test using CI Profilier?
Then you will be 100% sure. Furthermore - if the results are "close" you can just go with the option that suits your programming logic better.
p.s. you could also loop the multiple calls to the model into an array (like $projects) in the controller, and pass that variable to the view, so in either scenario the "view" is NEVER calling the "MODEL" directly.

Using multiple database tables in CakePHP

In my application, i have many methods that my controllers use commonly.
At first i copied them to controllers, then i found out that i must put them in AppController.
So i. reach those methods from derived controllers by "$this->commonmethod"
The methods that i put into AppController creates different types of data,
so i need to put them to 4-5 different tables in my database.
Most of the tables don't have a relation between each other.
But most of my controllers will use that tables to fetch related data for them.
(I checked the examples in cookbook, there are examples about Blogging,
category and tags. Where tables have relation between them)
Should i put my common controller code into a Plugin or Component? Or what would be the decision criteria?
Is it possible to use multiple database tables from a controller or a component?
Do Datasources or behaviours are suitable for this case.
Thank you in advance
It's hard to say what the best approach would be, given we don't know much about the database structure, what the controller methods do, and how they are used.
But one of your questions is very straightforward:
Is it possible to use multiple database tables from a controller or a component?
Yes, that is possible. Just create a model for each table (use public $useTable = 'tablename if cake cannot detect the table name automatically from your model names). Then, in AppController (considering your code will stay there), use this:
public $uses = array('List', 'all', 'models', 'you', 'need');
Best way is (if possible) to redesign the database, because in cakephp a good database design resolve half of your problems. If this is not possible then second one is use Components and using this component you can you multiple database tables.

question about the mvc pattern

i dont quite understand this pattern.
from what i have read, it looks like one model = one table (if you are using database to store data).
so if i've got a table called tags, i should have a tags model. and with a threads table i create a threads model.
then i got a tags controller and a threads controller right?
so what if i've got a tags_threads_map table for a many-to-many relationship.
should i have a tags_threads_map model eg. in which i get all threads containing a tag? should i have a tags_threads_map controller too?
would be great if someone could explain or give me a good breif tutorial on this.
the most tutorials just give a simple 1:1:1 example.
To fully understand MVC or any software design pattern, you really need to have a go at implementing it and see what your results are.
That said, MVC does not prescribe that one model = one table. In fact, a model could be backed by a number of tables, or even data originating in something other than a relational database (e.g. a web service, flat files, a key-value store or a graph database for example).
I would suggest that creating models and views that represent meaningful aggregates of related tables is probably a good approach. For example, to use the timeworn example of an Order and OrderLine table, an Order model might encapsulate operations on data that will ultiamtely end up in either the Order table or the OrderLine table.
Adhering to strict 1-to-1 mapping of table to Model, View and Controller will only result in an explosion of classes, some of which may not be doing much individually. Better to build Models and Controllers that are more focused on achieving some task identified by the business requirements, rather than just being a projection of the data model.
So the idea is less "one model = one table" and more that you don't want code that manages the data to be interleaved with code that manages the operations on data or code that handles user interaction. If you have some sort of persistance layer that handles mapping of objects to a database, that's enough to have a rudimentary model. If you have some separate code on top of that that does something algorithmic with that data, that's a controller. If you have a way of rendering the data for user consumption, that's a view.
Best example that comes to mind is a spreadsheet: the data in the spreadsheet is your model. If you have expressions in your sheet that manipulate the data, that can be seen as a controller. If you see the data in tabular form, or in a graph, those are two views. The views don't muck with the data or how it's calculated - they format it for your eyes. The controller doesn't format the data for your eyes - it creates / changes / calculates the data. The important part is separating out the concepts so you can, for example, write algorithms that don't care how data is stored, and views that don't care how data is calculated.
In my opinion, it's better to think of a model as a model of an object type, not of one specific table.
Generally, your MVC framework would handle your many-to-many relationships by definitions from within the models for tags and threads.
And you definitely don't need a controller for every model; controllers are generally more closely related to views (though there are usually multiple views to one controller).
This seems like it's too general of a question to be able to be answered to your satisfaction here.
A model can be more dynamic than that. For example, if you have a blog, and a blog has tags, your model might be called Blog and it can have a collection of Tags.
A model can be anything that stores the data. In the web app I'm working on there are several tables for contacts, their addresses which groups they belong to and so on. It's probably best to split them up by types, I should have made a group model but you don't strictly have to do this.
MVC relates to 3d games quite well, MVC is not only for information systems. Consider this:
In 3d graphics the model is map, the polygons and their positions and colours. The view is the camera from which the scene is viewed, a position, zoom and direction. The controller interprets the keyboard and mouse and manipulates both the camera(view) and scene(model).
If this were a shooter game then if:
A user pushes the forward button, the controller moves the camera forward.
A user pushes the throw grenade button, controller adds a grenade to the scene.
The view is presentation, the model is storage/structure and the controller is an in between which tells the view what to display and how to display it based on the state of the system.
Generally you put all the formatting in a view, data in models and logic into controllers.

Quick question about MVC in Php

Currently, I am working on restructuring an existing code base. I'm new to php frameworks, but I do know in general how MVC works.
Right now, there is one controller file, one model file, and thirty view files.
Should every model correspond to a table?
Should every view correspond to an html page?
What about the controller? How can I break this thousand line monster into more organized code.
Thanks.
Should every model correspond to a table?
No. A model is often constructed from data from multiple sources. Don't think in terms of tying it to your physical database structure even though there will probably end up being lots of similarity.
Should every view correspond to an html page?
Not to sound trite, but every view should correspond to a view. I'm not sure exactly what you mean by a "page".
Perhaps an example would be useful. Imagine a user registration page. The model is User and might contain fields such as:
Title
Given names
Surname
Date of Birth
Username
Address(es)
Email address
Phone number(s)
etc
Now, that data may be in multiple tables. For example: Party, Person, Contact and Address.
There will probably be several views:
About page
Form page (used for new registration and possibly editing details as well as errors);
Success page;
Failure page.
Typically all of this will be handled by a single controller as all the processes are inter-related.
Every model should correspond to a logical data object - which should generally predominantly be stored in one table (often with foreign keys into other tables, since models generally need to reference other models).
Every view should correspond to a logical way of viewing your data (e.g. on stackoverflow, there is hopefully a view for the list of badges pages, a view for the list of tags pages etc).
Every controller should correspond to a logical grouping of views, which should not be too big (where too big is the line where the file is becoming unmanageable - if you've got 30 views, you can hopefully find a logical way to group them into say 3 controllers).
What about the controller? How can I
break this thousand line monster into
more organized code.
Have a look at CakePHP framework and how it solves the problem of large models, controllers, and numerous views. I find it quite elegant. Complex models can have behaviours. Large controllers can be broken into components. And numerous views are grouped with layouts, while having common bits separated into elements. It might sound complicated and scary at first, but once you try to use it, it really falls into place.
Should every model correspond to a
table?
It doesn't have to but it often will depending on the complexity of your business logic.
Since you're refactoring an existing application, think about how the model is used by the other layers. In MVC, the model is at the bottom of the dependency stack.
How will the view access the model? How will the controller modify it? How will the model be populated?
Should every view correspond to an
html page?
Again, it doesn't have to but it often will.
What about the controller? How can I
break this thousand line monster into
more organized code.
A common strategy is using the front controller pattern. The front controller deals with HTTP requests, application initialisation and site-wide logic (just as your thousand line monster is currently doing) - but then it delegates to more specialised controllers.
These specialised controllers could be grouped by the models it uses, site page structure, or anything else that seems logical. They then interact with the model and select a view to display.
Finally, +1 to frameworks as Leonid suggested. Even if you don't end up using one, there are some great implementations of controller patterns out there.
Hope that helps.

Categories