I've starting using Codeigniter for a project recently (few months ago) but its getting a little out of hand with a bunch of models that need to interact with each other and I was wondering if I should be creating a library instead?
In my case, I have a user action that happens when you win a game and it would get logged in my user_model but I also want it to get put in my events_model?
Should something like this that affects multiple models become a library?
I know it should NOT be in the controller because I'd have to reuse this trigger in multiple controllers (might not make sense for the provided example but does for my application).
Libraries are meant to provide reusable functionality for your application, while models in the MVC architecture represent the data logic in or the actual data used by your application.
So to answer your question, you can implement a library that handles updating of multiple models. Just ensure that things like database inserts are handled by your models themselves, as that is business logic more than application logic.
You could leave your models modularised as they are and write your logic in libraries, this way you can access mutilple models though a single function in a library, without making your controllers untidy by loading multiple models and having none-interface orientated logic mingled in with interface logic.
Related
I've written a small RESTful PHP backend using the Slim framework (http://www.slimframework.com/) that interfaces with a MySQL database, and right now I just have one class doing all the DB interactions and it's getting kinda big. So it's time to organize it a little more cleanly.
So based on what I understand from MVC, a better way to do this might be to implement a model layer like so:
each logical entity in the system will be implemented with a data class. I.E. user accounts: a class called "Account" with getId(), getName(), getEmail(), etc etc
and corresponding factory objects, i.e. AccountFactory which owns the DB connection and creates an Account class to manipulate elsewhere in the business logic layer.
The business logic layer would still be pretty simple, maybe a class called MyApplication that instantiates factories and uses them to respond to the RESTful API calls.
Business logic might be, for example, matching two accounts together based on geographical location. So in this case, I would just be testing on the data in two separate Account objects instead of the raw data loaded from the database.
But that seems like a lot of refactoring time spent to do basically the same thing. Why wouldn't I want to just use the plain array data I load from the database? It's not DB-independent, sure, but I don't really plan on switching away from MySQL at the moment anyway.
Am I approaching this in the correct way?
Well, partly.
The first point describes a model - the M in MVC. Abstracting your "business logic" from this model makes sense in many ways. One use case could be a website that interacts with the same data as the REST API. You could reuse the model and only need to build new controllers.
The "business logic"/"layer" would probably the controller - the C in MVC. However I would not give the factory objects ownership of the DB connection, as some use cases may want to use multiple factory objects but should use the same database connection...
I suggest you read more about the structure and pro's and con's of the MVC approach.
when you start from scratch the best is to :
have a ORM (which mean that you must have relations in your MySQL database with foreign keys etc.). Thats very quick way to manage database management in your program.
Create your home-made class for each entitiy = 1 class.
The best pratices are generally to have an ORM but it can be a bit heavy (it depends on your architecture and application).
In your case put an ORM seems to be a lot too much cause you developped a lot.
It depends of the future of your application : will it grow again ? will a lot of developper will develop on it ?
For a small/medium size you can easily refactor a bit your class by big theme, ex : 1 class for your 3 biggest entity in which you have the more requests. That will tidy a bit the mess and organize things, and then you can migrate your new classes for eqch new entity. For the old ones you can migrate step by stepm or not
Another good practice is to have getters and setters $this->getter_id(); $this->setter_id( $in_nId ); That will help you a lot if you need to change some db fields
I'm currently designing a game that utilises CodeIgniter, but I don't think the singleton approach to models is the way I want to handle the game-related objects in the DB.
I want to use a CodeIgniter Model class to handle the basic CRUD operations of the objects, but have the objects as PHP Classes.
Example:
$this->load->model('playermodel');
$player = $this->playermodel->get($player_id); // Returns a Player object
// Call modifying operations on the player (equip item, take damage etc.)
$this->playermodel->save($player); // Commits updated Player back to DB
$player2 = $this->playermodel->create(); // Basically calls new Player()
I'm fairly new to CodeIgniter, would something like this be going against any kind of CodeIgniter or MVC design rules? And if so, could anyone recommend me another approach to my problem?
The best approach would be for you to get as far as you can from Codeigniter, if you want to build proper MVC. Codeigniter is framework written for PHP4, and it didn't get any updates for quite some time now, I'm talking about framework design, not some library updates.
If you look at Codeigniter source code and look what base model do, it just takes request from model and pass it back to the controller using magic _set and _get methods. So Codeigniter doesn't really know a difference between your models or controllers. And how every you write this, everything is processed in some mega super ultra global object.
From outside it might look like you are using MVC but you are not really.
Take a look at Zend2, Symfony2... where you can really build your Models.
What you currently have is a strange interpretation of data mapper pattern (do not confused with CI's ORM with same name, which instead implements active record pattern).
The idea would be to separate the domain logic from the interaction with storage abstraction. For simplified code example, you can read this post.
Only major problem, that i sea with your implement, is that your mapper also contains logic for creation of instance. Thus, it has acquired also the characteristics of a factory (or maybe, builder .. depends on your particular use-case). This would violate single responsibility principle.
But non of this is against CI's design rules. Because it has none.
I am building a CRM using a framework (codeigniter) for the first time and I am having trouble determining where a certain module should go while maintaining the MVC methodology. The module automatically generates a new user (when a new company is created) and emails the log in details out to the supplied email address.
I am familiar with the idea of skinny controllers and fat models but to compile all the information needed the module must request data from several different tables as well as inserting data into several tables.
The scenarios I have considered so far:
The logic is in the model where most of the information comes from.
Create a totally new model that deals with just this module and the multiple tables required.
Place the logic in the controller that deals with creating a company.
Create a new library or helper and call the module when it is needed.
Skinny controllers and fat models seem to suggest that one or two are the right options but I was lead to believe that a model should only deal with one table in the database.
What is the right approach to ensure adherence with MVC?
Codeigniter allows you to be flexible with your MVC approach. So the answer is which option is:
Easiest for you (or your team) to understand
Easiest to code maintain
Easiest for someone else to understand
There's no point putting your code into a library, if you dont have any other libraries and dont understand libraries. Same as if all your models are "fat", but only point to one table, do you want this model to be the only one that also points to 4 other tables?
Personally, if this "logic" only ever happens in one place, then I would place it into the controller, and call the 4x models you need to do each bit of the code.
If this "logic" occurs in multiple places, I would place it into a library and call it when needed.
the situation is this.
my client (who also is a programmer) asks me to develop an address book (with mysql database) with a lot of functions. then he can interact with some class methods i provide for him. kinda like an API.
the situation is that the address book application is getting bigger and bigger, and i feel like its way better to use CodeIgniter to code it with MVC.
i wonder if i can use codeigniter, then in some way give him the access to controller methods.
eg. in a controller there are some functions u can call with the web browser.
public function create_contact($information) {..}
public function delete_contact($id) {..}
public function get_contact($id) {..}
however, these are just callable from web browser. how can i let my client have access to these functions like an API?
then in his own application he can use:
$result = $address_book->create_contact($information);
if($result) {
echo "Success";
}
$contact = $address_book->get_contact($id);
in this way, my controller methods are handling the in and out with the Models. there will be no views, cause i just have to return the data/result from the Models. and he can just use my "API" functions.
is this possible?
cause i just know how to access the controller methods with the webbrowser. and i guess its not an option for him to use header(location) to access them.
all suggestions to make this possible are welcomed! even other approaches to let me use CI to develop. perhaps there already are best practices regarding this kind of cross framework collaboration?
thanks
MVC seems to have dispersed in its definition. This definition I will offer should be ideal for you.
Models are where you build your business end of the application. Operations such as create_contact, delete_contact, and get_contact belong in the model layer. The model layer is what builds your application API and should be entirely independent.
Consider the controllers purely as the user's puppeteers. Controllers accept user input - the validation, sanitation, and whatnot may be done elsewhere - and invokes the API you've already setup in the model layer. Also, controllers then specify what view to use - however complicated or simple your presentation layer is.
The presentation layer usually isn't the difficulty. As long as you are only using read operations in the view you should be fine.
To clarify, if a user wants to create a new contact, the controller may need a method called create_contact that accepts the appropriate input. However, the actual operation of creating the contact must be done in the model layer. This will allow your other developer to reuse that same operation in a completely different application by loading your model, which was already designed as an independent entity.
I was just curious as to what the rule of thumb was for models. Generally, I use them only for situations where I need to add/edit or update database entries for an object.
However, I'm building an app at the moment that has a "config" table which holds various data, such as last updated, which will control when certain features in the app should be displayed. In this instance, I will mostly need to retrieve data from the config table. Is it worth putting these config methods in model?
I'm interested to hear how more experienced coders approach the MVC methodology in CI - example pseudo methods (e.g., what methods relating to the same object you'd use in the model and the controller) would be most helpful.
"Is it worth putting these config methods in model?"
yes, absolutely, if only to prevent you from writing the same getters and setters in every controller that has deal with your table of configuration settings. Write your getters and setters once (ideally in a generalized way in MY_Model) and write your complex queries once in the model, then call them in as many libraries, controllers, or views as desired.
By employing models you are able to code to an interface and not an implementation.
Meaning there is a benefit of abstracting your model from your controller in that your controllers can be agnostic as to what ways your data is stored. You can decided to switch your data from database to xml to ini files as long as the models methods consistently offer up results in the format the controller expects. In short, when you switch your data source, you'd need only update your model's internal methods and not your controllers.
Lastly, it is permissible by the rules of MVC, I believe, to allow views to request data directly from models. To this end you may build CodeIgniter helpers for use in views that use the model to retrieve configuration settings, in much the same way that the native config_item() common function works.
You separate the M from the V&C for many of the same reasons that you separate your CSS from your HTML - abstraction, ease of reuse and lighter, more readable code.
Also note that with other MVC platforms, you wouldn't have a choice. Just because you can ignore the methodology (in CI) doesn't mean that you should do so.