Can I call a Model from a View?
Can I call the model from the View?
Yes, you can. As long as you maintain the separation of concerns between M,V and C, you are free to call upon the Model (or the Controller) from the View. Most MVC diagrams show a bidirectional connection at least between View and Model. What you don't want to do though, is place logic/code from the Model (or the controller) into the View and you don't want to modify the model from there.
For example, you might have a widget on your page that aggregates the latest ten blog posts headlines from your favorite blogs on each page of your website. You get the headlines by calling, say MyFavFeeds::getLatest();
in your model. What are your options now?
- You could add the code to fetch the headlines into the controller, but that would require you to replicate it in each and every controller action, which is against the DRY principle. Also, the controller's concern is handling user input for specific actions and fetching the headlines on each call is likely not even related to these actions.
- If your architecture supports it, you could fetch that data in some sort of preDispatch hook, that is, the headlines get loaded and injected into the View from a plugin or callback. That would be DRY, but a second developer might not be aware of that plugin and accidently overwrite the variable holding the headlines from his controller action. And there might be cases in which you wouldn't want to load the headlines, e.g. when just rendering confirmation pages for form submissions, so you'd have to have mechanism for disabling the plugin then. That's a lot to consider.
- You place the call to (not the code of)
MyFavFeeds::getLatest()
into the View or Layout template or, better, a ViewHelper, that encapsulates the call to your model class and renders the widget. This way you don't have to worry about overwriting any variables or repetition. And when you don't need the headlines on your view, you simply don't include it.
About your other question:
In my View, I'm calling a Model that
runs my authentication system, and
requesting the login status of a user.
I then use that boolean to decide
whether to show certain elements
within the view, and where to place
others.
Authentication is something you will want to do early in the application flow, before any controller actions are called. Thus, you should not run your (entire) authentication system in the View. The actual authentication is not View-related logic. Just requesting the user status after authentication, on the other hand, is okay. For instance, if you want to render a widget showing the user name and giving a login/logout button, it would be fine to do something like
<?php //UserHelper
class UserMenuHelper
{
public function getUserMenu()
{
$link = '<a href="/user/logout">Logout</a>';
if(MyAuth::userHasIdentity()) {
$link = sprintf('<a href="/user/logout">Logout %s</a>',
MyAuth::getUsername());
}
return $link;
}
}
If you got larger portions of your GUI to be modified by a User's role, you might want to break your View apart into partial blocks and include them based on the status, instead of writing all the HTML into a View Helper.
If you are only looking to render a navigation based on the user role, have a look at Zend Framework's Zend_Navigation
and Zend_Acl
to see how they do it.
Calling a model within a model in a view. (asp.net MVC)
Try loading Producer
data explicitly, by calling function Include()
public ActionResult Index()
{
var movies = from m in db.Movies.Include(b => b.Producer)
select m;
return View(movies.ToList());
}
If lazy loading is enabled, your property Producer
would be loaded first time it is needed. However, if lazy loading is disabled, you need to explicitly specify that you want to load other related entities.
The method Include
that accepts a lambda is an extension method, so you will need to add this using at the top of your file:
using System.Data.Entity;
Alternative is to specify include by using string:
public ActionResult Index()
{
var movies = from m in db.Movies.Include("Producer")
select m;
return View(movies.ToList());
}
The result is the same, but first approach does not contain "magic strings", which is often preferable.
How do I call a model method into a view?
from here:
Django models like everything in python is an object, so you can call the custom method after instanciating it, but don't forget that i.foo
is treated as an attribute and i.foo()
is a method.
How to call a model function in view Yii?
I prefer to put it on your controller, like this
$model_result = MyModel::model()->test();
$this->render('view', array('model_result' => $model_result));
On your view.php
<div class="my_class" >
<?php echo $model_result;?>
</div>
Calling model function in view codeigniter
MVC or not to MVC
The first thing I should note is that It is impossible to write classical MVC in PHP. In fact the MVC-like PHP frameworks such as CodeIgniter or Yii implements sort of MVP in which:
- view is passive and unaware of model
- presenter (controller) changes state of model, reads information and passes it to view
Credits to tereško
CodeIgniter Approach
However, particularly in CodeIgniter, you have 3 steps:
- Create a Model to query through the database and return the data (as an array or object)
- Create a Controller to load and fetch the result from the Model (a method of the Model), and pass the returned data to the view
- Create a View and use PHP loops to echo the result out, build the HTML.
Getting all together
Considering the above approach, you need to fetch the result from the database in your Model:
application/models/product.php
class Product extends CI_Model
{
public function get_product($product_id)
{
$this->db->select('*')->from('products');
$this->db->where('product_id', $product_id);
$this->db->join('versions', 'versions.product_id = products.product_id');
$query=$this->db->get();
return $query->first_row('array');
}
}
Then fetch and pass the result within the Controller:
application/controllers/products.php
class Products extends CI_Controller
{
public function view($product_id)
{
$this->load->model('product');
// Fetch the result from the database
$data['product'] = $this->product->get_product($product_id);
// Pass the result to the view
$this->load->view('product_view', $data);
}
}
Finally, use the returned data in the view, to generate the list:
application/views/product_view.php
// Use $product to display the product.
print_r($product);
Call Method in Model Class Based view
One option is to add extra actions to your view. So someone can accept or deny a booking by doing one of these HTTP requests:
PUT /bookings/1/accept/
PUT /bookings/1/deny/
You can achieve this with something like:
# models.py
class Booking(models.Model):
...
def accept(self):
self.status = self.ACCEPTED
self.save()
def deny(self):
self.status = self.DENIED
self.save()
# views.py
from rest_framework.decorators import action
from rest_framework.response import Response
class BookingView(viewsets.ModelViewSet):
...
@action(detail=True, methods=['put', 'patch'])
def accept(self, request, pk=None):
booking = self.get_object()
booking.accept()
return Response({'status': booking.status})
@action(detail=True, methods=['put', 'patch'])
def deny(self, request, pk=None):
booking = self.get_object()
booking.deny()
return Response({'status': booking.status})
Related Topics
Requires Ext-Fileinfo. How to Add That into My Composer.JSON File
PHP Startup Unable to Load Dynamic Library PHP_Mongo.Dll
Get Youtube Video Id from HTML Code with PHP
The Advantage/Disadvantage Between Global Variables and Function Parameters in PHP
What Does This Mean in Documentation: Square Bracket Followed by Comma ( [, )
Populate Another Select Dropdown from Database Based on Dropdown Selection
Unexpected Character in Input: '\' (Ascii=92) State=1
Casting an Array with Numeric Keys as an Object
PHP Recursion to Get All Possibilities of Strings
How to Add a Delete Button to a PHP Form That Will Delete a Row from a MySQL Table
Convert Ascii to Utf-8 Encoding
How to Extract Images from a PDF File
Understanding Nested PHP Ternary Operator
Close Open HTML Tags in a String
Access Get Directly from JavaScript
Pdo MySQL: Insert Multiple Rows in One Query
Expected Response Code 220 But Got Code "", with Message "" in Laravel