Suppose I have these models - Post, Category, User. Post belongsTo Category and User.
In my PostsController inside some action I want to get data from categories or users table I can use one of the following
1) public $uses = array('Post', 'Category', 'User') and use Category model like
$this->Category->find('all'); everywhere in that controller
2) $this->Post->Category ->find('all');
3) $this->loadModel('Category '), than use
$this->Category->find('all') in that action
So, my question is which one of these will have the best performance and why ? Maybe for small applications it won't have any visible effect, but what if the project is big and there are dozens of models that should be used in the same controller and every little performance improvement does matter.
Thanks
If you already have the association in the model, use that (#2). This makes sense because these models would most likely already be loaded (if you're not caching).
Otherwise, use the loadModel function. This way you'll be loading the model only when you need it. Either way, unless you have some major work going on in your constructors (you shouldn't), it really won't matter that much.
Related
While working with Unity, I realized that separating Model and View would make my code more readable and straightforward. Constructing the whole model, all I had to do is just create some UI and bind it to Model.
But I still don't understand what 'Controller' is, and why does it exist. I don't think I had trouble when I directly bound View to Model, not through Controller.
So the question is if we can bind View to Model directly, why do we need Controller? What's the benefit of having Controller between Model and View?
At the highest level the Controller is the link between the View (displaying the UI/UX) and the Model (creating and managing your database and its tables).
True, it is possible to write code without any Controller usage but your Views will quickly get very cluttered and each file will be full of logic that is much more nicely stored somewhere else hint hint.
The Controller (and Model and some other places such as helpers) is thus the perfect place to sort out all the back-end code so that all you need to do is send a single field or object to your View to display.
An example is somewhat painful because by its nature the Controller is where you go to sort out your code as things get more complicated but this is a great article to get you on the right track! HTH
https://www.toptal.com/unity-unity3d/unity-with-mvc-how-to-level-up-your-game-development
I don't have years of experience, but in my understanding controllers provide a bridge across view and models. While view contain the pretty part and models contain useful parts the controller do the calls of functions passing values from database to view or inputs to model. That provide a way to avoid lots of injection like class A calling class B, calling class C, etc.
You can put rule business in controllers or in view, but thats not the expected in MVC architecture. The first important thing (for me) in software programming is readability, whats MVC provide.
if you've interest, search for other architectures like MVVM, to compare then.
I'm wondering whether it is possible/advisable to use instances of a laravel model instead of using the Facade. Why all this trouble? I have a model which will be used with many tables, and i want to be setting the model's table automatically using the constructor. Is it possible/advisable, or what is the best approach of achieving the same end?
I have researched around with no much success.
UPDATE
THis is the scenario: an exam system, where different exams are "created". after an exam is created, a table is created in the database under the name Exam_#, where # is the ID of the exam. I want to access all exam from one model: Exam, but you see the particular table the model is to use can vary significantly, so we cannot set the table variable statically. The model shall not know the table it will use until it(the model) is called. So thats why i was wondering whether i can be passing the ID of the exam when i am calling the model or something like that. I hope my question is now more clear.
At the end of this, Laravel is still PHP... Anything you can do in PHP can be done in Laravel.
is (it) possible/advisable to use instances of a laravel model instead of using the Facade?
You can achieve exactly the same results using an instance of the model as you would using the static facade.
$user = User::find(1);
$user2 = new User();
$user2 = $user2->find(1);
Both instances of the above model contain the same results.
Is it advisable? I really don't like the static facades at all, they bring with them more trouble than they are worth, especially when it comes to testing (despite being able to mock them, they create tight coupling where most of us need loose coupling). My answer to this would be: don't use the facades at all.
What is the best approach of achieving the same end?
As #JoelHinz suggested, create a base model with common properties and then use the models as they are intended. i.e. ONE table to ONE model and create the relationships between them. Don't use the same model for multiple tables, this is not how Laravel models were intended and you will lose a lot of the power Eloquent provides by taking the approach you mentioned.
Updates from comments
To get you started with testing in Laravel this is a good end to end tutorial Tutsplus Laravel4 + Backbone. Ignore the backbone part, what you're interested in is the testing parts that start about a 1/3rd of the way down the page. This will get you testing controllers straight away and introduce you to the repository pattern to create testable DAL structures.
Once you get the hang of writing tests, it becomes very easy to write a unit test for anything. It may seem like a scary subject, but that is purely down to not understanding how it works, it really is quite simple. Take a look at the PHPUnit documentation as well, it is an excellent resource.
I have actually 3 questions, but similar to each other:
I have a model called Permissions. and I need another model ie. Users. what is the proper way to user Permissions inside Users.
You get what I mean above, is that weird or is there another better way to do it.
This Permissions model, will be used globally throughout my application, what is the way to use it in other models or controllers (similar with 1st question)
One way is to get the global variable for the main CodeIgniter object, and then load the model from that object rather than $this:
class Permissions extends Model
{
function MyPermissionsFunction()
{
$ci =& get_instance();
$ci->load->model('users');
$ci->users->MyUserFunction();
}
}
You can also sidestep the issue by combining your models together into one larger model. The main reason to keep them separate is to only load the models that you need; if you nearly always use both together (as would make sense, for Users and Permissions), you may be better off taking this approach.
Where should intermediate code be placed? (something that ins't just storing/retrieving data from DB nor processing requests/views)
For example,
Say I have Listings and I create CRUD functions in the model. These Listings may require more complex tasks such as pausing and resuming, which may require some time calculations, error setting, etc. Should these be placed in the model or should I wrap a simple model in a library and use that as a middleman for the model?
At the moment I'm thinking of using Drivers/Libraries and keeping models rather simple, except for some dynamic SELECT filters. I'm getting a bit confused though, since I'm guessing I'd probably have to recheck variables, dependencies, etc in the model after doing it in the library, yes?
I'd most likely either squish everything together in the model and check once or separate and check twice?
The general rule of thumb is:
1) Perform all business logic in the models.
2) Perform actions like a traffic cop would in controllers. (directing users to new views based on results of activities.)
3) Perform only presentational logic in views.
Anything else that you would like to do that would be considered, "intermediary", could reside in a Library or Helper.
It should be noted though that if you write a Library, don't forget to get an instance of the current CI object in your class so that you have it to use with your internal class methods.
class Your_lib {
$CI =& get_instance();
...
}
Hope that helps.
CodeIgniter has a method $this->load->vars($array) that is ideally used in the parent Controller to provide global access to system variables directly in the view. For example:
$this->data['username'] = "john";
$this->load->vars($this->data);
Then in the view, you can easily access john by echoing $username.
My question is, is it possible to use $this->load->vars($array) from within a Model instead of a Controller? This will allow me to abstract away some details from my Controller, making it cleaner. What changes would I have to make to get this working? Would you recommend it; do you think it breaks MVC?
Also, I'm using Datamapper ORM, so my models actually extend the Datamapper object and not the Model object.
Thanks!
Is it possible to use $this->load->vars($array) from within a Model instead of a Controller?
As mentioned, yes you can do this, you can even load a view from a Model, or even run $this->load->vars() in a view and load yet another view.
This will allow me to abstract away some details from my Controller, making it cleaner.
This is like sweeping the dirt under the rug, it didn't go away - it just went somewhere else where you are bound to deal with it later.
Would you recommend it; do you think it breaks MVC?
It's not going to "break" anything, but it implies that maybe your concept of MVC is somewhat broken. If it has nothing do do with the data layer and everything to do with the view layer, it doesn't belong in the Model. There's a good chance there may be some other stuff that doesn't quite belong there as well...
I'm using Datamapper ORM, so my models actually extend the Datamapper object and not the Model object.
You may need to call get_instance() and assign it to a variable or class property for use in DM models, so you can access the Codeigniter object.
Example: $CI =& get_instance(); $CI->load->vars();
Suggestion:
Return the data from the Model in the simplest, most reusable form possible, and then assign it to the view variables in the Controller. If I'm hunting down the source of some variables in a view file, the last place I'd look for them is in the Model. You may end up revisiting this project in the future, so try to be consistent as much as you can, and stick to the suggested, expected practices.