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.
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 wanted to ask, looking from the 'best practices' side, which solution is better, getting a form data in Controller and passing it to Model, or retrieving it directly in the Model?
I use the first solution, which makes your controller methods very long and ugly, but I think it is still the right choice. But recently I have seen some other projects source code where the form data is retrieved in model, but it seems that it breaks the rule, where the model should not know, where the data comes from.
So which is the better practice?
As #lukasgeiter said in the Comments, I also say this would typically be done in the controller.
You may want to have a look at the corresponding laracasts on
MVC
Models
Controllers
Basically, you already said it. Models are just kind of "storage-interfaces" while Controllers are places, where the logic happens.
Also, have a look at MassAssigment, which cannot be done within the Model itsself but in the controller. This might be of interest in your case (without knowing the details).
I'm using Codeigniter to build a web app, and I'm trying to follow proper OOP, MVC and Codeigniter convention. A few things are definitely escaping me. Below is a simplified explanation of what's confusing me.
I have a 'companies' table and a Companies_model. This model has private variables like id, name, and url. This model has a method named load_data( $id ), that uses an id to load all the data about a company into the class variables. This $id is coming from the URL. Finally, this model has public getters that return the values.
I have a profile page on my website for every company in my system. In my Companies controller, I load this company's data in the following way.
$this->load->model( 'Companies_model', 'Companies_profile' );
$this->Companies_profile->load_data( $this->uri_company_id );
When my other logic is complete in the controller, I have the following code to render the view:
$this->data['Companies_profile'] = $this->Companies_profile;
$this->load->view( 'profiles/companies_profile_view', $this->data );
In my view, I render data like this:
<p>This company's name is <?php echo $Company_profile->get_name(); ?>.</p>
All of this seems redundant. Why am I passing data to the view when it's already available in a specific instantiation of the Companies_method? I feel confused and that I'm doing something wrong, but I can't figure out what that is. Perhaps I'm not doing anything wrong, but haven't encountered the reason for some of this structure yet. Overall, my app is fairly simple. Can someone shed light on how to properly organize and pass data to views? Why pass the data, and not just make it all available in CI's base class, $this?
NOTE: I have multiple instantiations of the Companies_model on every page I render because I have a list of related companies on each profile page.
That is MVC, at least the way it's done in CodeIgniter. Separation of displaying values from retrieving them from the database. In such simple cases, the advantages are not really visible.
Imagine you later decide to change the database structure. You would only need to rewrite the model to return the same classes and leave front-end code intact. You can also give the view to some web designer to design, without telling him anything about database structure, etc, etc.
One of the main advantages of MVC shows up when you work in teams. Instead of coming up with your own conventions, everyone can do the stuff uniformly.
Passing a class object to he view breaks the idea behind MVC. MVC is designed to break up the parts of programming into 3 aspects. The Model, View and Controller. What you pass to the view are only things that the view needs. The view probably doesn't need the entire object. It probably only needs certain bits of information from the object. It allows you to keep the business logic away from the visual design. It allows a web designer who knows HTML and a little PHP to go in and make changes without having to know how your objects work. he sees.
<?php echo $company_name ?>
which is a lot easier for a non technical person to interpret than
<?php echo $company->getName(); ?>
If you follow the quickstart guide provided by the official Model-Glue docs, found here:
http://docs.model-glue.com/wiki/QuickStart/2%3AModellingourApplication#Quickstart2:ModelingourApplication
It will seem like the "model" is a class that performs an application operation. In this example, they created a Translator class that will translate a phrase into Pig Latin. It's easy to infer from here that the program logic should also be "models", such as database operation classes and HTML helpers.
However, I recently received an answer for a question I asked here about MVC:
Using MVC, how do I design the view so that it does not require knowledge of the variables being set by the controller?
In one of the answers, it was mentioned that the "model" in MVC should be an object that the controller populates with data, which is then passed to the view, and the view uses it as a strongly-typed object to render the data. This means that, for the Model-Glue example provided above, there should've been a translator controller, a translator view, a PigLatinTranslator class, and a Translation model that looks like this:
component Translation
{
var TranslatedPhrase = "";
}
This controller will use it like this:
component TranslatorController
{
public function Translate(string phrase)
{
var translator = new PigLatinTranslator();
var translation = new Translation();
translation.TranslatedPhrase = translator.Translate(phrase);
event.setValue("translation", translation);
}
}
And the view will render it like this:
<p>Your translated phrase was: #event.getValue("translation").TranslatedPhrase#</p>
In this case, the PigLatinTranslator is merely a class that resides somewhere, and cannot be considered a model, controller, or a view.
My question is, is ColdFusion Model-Glue's model different than a MVC model? Or is the quickstart guide they provided a poor example of MVC, and the code I listed above the correct way of doing it? Or am I completely off course on all of this?
I think perhaps you're getting bogged down in the specifics of implementation.
My understanding of (general) MVC is as follows:
some work is needing to be done
the controller defines how that work is done, and how it is presented
the controller [does something] that ultimately invokes model processing to take place
the model processes handle all data processing: getting data from [somewhere], applying business logic, then putting the results [somewhere]
the controller then [does something] that ultimately invokes view processing to take place, and avails the view processing system of the data from the model
the view processes grab the data they're expecting and presents that data some how.
That's purposely very abstract.
I think the example in the MG docs implement this appropriately, although the example is pretty contrived. The controller calls the model which processes the data (an input is converted into an output), and then sets the result. The controller then calls the view which takes the data and displays it.
I disagree with the premise of this question "Using MVC, how do I design the view so that it does not require knowledge of the variables being set by the controller?" The view should not care where the data comes from, it should just know what data it needs, and grab it from [somewhere]. There does need to be a convention in the system somewhere that the model puts the data to be used somewhere, and the view gets the data it needs from somewhere (otherwise how would it possibly work?); the decoupling is that model just puts the data where it's been told, and the view just gets the data out from where it's been told. The controller (or the convention of the MVC system in use) dictates how that is implemented. I don't think MG is breaking any principles of MVC in the way it handles this.
As far as this statement goes "In this case, the PigLatinTranslator is merely a class that resides somewhere, and cannot be considered a model, controller, or a view." Well... yeah... all a model IS is some code. So PigLatinTranslator.cfc models the business logic here.
And this one: "In one of the answers, it was mentioned that the "model" in MVC should be an object that the controller populates with data, which is then passed to the view"... I don't think that is correct. The controller just wrangles which models and which views need to be called to fulfil the requirement, and possible interchanges data between them (although this could be done by convention, too). The controller doesn't do data processing; it decides which data processing needs to be done.
Lastly, I don't think the "strongly-typed" commentary is relevant or an apporpriate consideration in a CF environment because CF is not strongly typed. That is a platform-specific consideration, and nothing to do with MVC principles.
I think one of the common confusions around MVC is that there are multiple Views, multiple Controllers but only one Model. cfWheels has a "model" object for each persistent domain object which I think is very confusing - but of course cfWheels is drawn from Ruby on Rails which also uses "model" in that context.
In general, in MVC, "The Model" represents your business data and logic as a whole. The Model is made up of a number of domain objects (which are typically persistent) and a number of service objects (which exist to orchestrate operations across multiple domain objects). In real world applications, you typically have a data layer that manages persistence of domain objects - which may be partitioned in a number of ways.
It may also help to think of the input data that the view needs as it's "API" and it is the controller's job to satisfy that API by providing compatible data. Think of it more that the controller needs to know what type of data will satisfy the view rather than the other way around.
The framework I'm using on my project follows the MVC Pattern. I"M building JSON feeds and need to structure them in a different way then what the system gives me by default from the ORM. Where should I be handling the task of mangling and shaping my data that I'll serve up, in the model, view or controller?
Right now I'm doing it in my controller, then passing that data to the view. I can see this fitting better under the Model or the View but not sure which one.
If this different structure is only relevant to the view, you should keep it in the view.
If this structure is used in more than one view, make a Helper for it.
Internally your app should standardize on one data format, so models should always return a standardized format. If you were to do something with that data in your controller, you'd need to change the logic for interacting with the data just in that one controller function, which in this case doesn't make much sense. If you later decide to change the format in the model, you'd also need to change code in the controller that interacts with it. Don't create dependencies when there's no advantage to do so.
I'd write a model method to do it if I were you. Having it in the controller will make your controller fat, which is bad, and means you can't call that functionality from other controller actions or anywhere else. Although it could be considered presentation logic, I prefer to keep my views really simple with just conditionals and iterators at most. There may be an argument for having it in a helper, but I'd still stick with the model.