Love Fuel?    Donate

FuelPHP Forums

Ask your question about FuelPHP in the appropriate forum, or help others by answering their questions.
Is it bad pratice to pass ORM objects (or other complex objects) to views?
  • Hi guys, This is a noobish question, but is it bad practice to pass complex objects to your views? Put another way, should views only be passed arrays and scalar values? Should they be as dumb as possible? For instance, let's say... * A Model_Parent has a name and many Model_Kid.
    * A Model_Kid has a name and a Model_Puppy.
    * A Model_Puppy has a name. If I want to list the puppy names of a parent's children in a single view, how should I pass the data? (Simplifying assumptions: each model has a property called "name"; the models are related correctly; the kids and their puppies have been found and set/hydrated in the Model_Parent object) * Scenario 1: Pass the Model_Parent object ($parent) to the view. In the view...
    <h1><?php echo $parent->name; ?>'s puppies:</h1>
    <ul>
        <?php foreach ($parent->kids as $kid): ?>
            <li><?php echo $kid->name; ?> has <?php echo $kid->puppy->name; ?></li>
        <?php endforeach; ?>
    </ul>
    
    * Scenario 2: Pass the parent's name ($parent_name) as a string and the kids as an array ($kids). In the view...
    <h1><?php echo $parent_name; ?>'s puppies</h1>
    <ul>
        <?php foreach ($kids as $kid): ?>
            <li><?php echo $kid->name; ?> has <?php echo $kid->puppy->name; ?></li>
        <?php endforeach; ?>
    </ul>
    
    * Scenario 3: Pass parent's name as a string ($parent_name), kid names as an array ($kid_names), and puppy names as an array ($puppy_names). In the view...
    <h1><?php echo $parent_name; ?>'s puppies</h1>
    <ul>
        <?php foreach ($kid_names as $key => $kid_name): ?>
            <li><?php echo $kid_name; ?> has <?php echo $puppy_names[$key]; ?></li>
        <?php endforeach; ?>
    </ul>
    

    This is my first true MVC site, and I'm using Scenario 1 right now. It's easy enough, but it seems like the view knows too much about how my models are related. I have the sinking suspision that I'm setting myself up for a headache in the future. What do you think? Thanks for the help! Go FuelPHP!
  • Thanks WanWizard. I changed my mind about passing ORM objects. I use my ORM objects less for creating forms (where your solution above is money) and more for selecting data. But, unless I have to, I think I'll try to keep from passing them directly to my views. I don't like the fact that my views could inadvertantly be executing database operations.
    If the related Model_Kid wasn't found beforehand, echo $parent->kid->name would select a parent's kid from the database in the view. I don't like the fact that my view is getting much more data than it actually needs.
    For example, a Model_User might contain an id, name, created_at, login_hash, and much more, but I just need the user's name in the view. I don't like the fact that my view is intimately knowledgable of my model relations.
    The view shouldn't care how it gets the names to display, it just needs a list of names. With respect to viewModels, it's a different story. I find myself passing ORM objects to viewModels all the time. Then, I use the viewModel to reduce the ORM object to the data that's needed by the view. For example, my controller would pass a Model_User object to my users/update viewModel. The viewModel would then cherry-pick the user's name, email, birthday, and timezone and send them to the view. I love viewModels. When I first started, my controllers were full of "supporting" code that didn't have anything to do with the request. They set the template's page title, metadata, added js scripts and more. As I started to respond in multiple formats (e.g., html, mobile, and json), my controllers had tons of if/then statements checking the response's format and deciding what to do. I decided that was the view's job, and I created a viewModel for each view. Now, my controllers are lean and response-format-agnostic. Your old posts helped me wrap my head around viewModels and responding in different formats. Thanks for all your help WanWizard:
    * ViewModel vs. View
    * Folders for different view formats
  • I don't see a reason why you shouldn't pass an ORM object to a view.
  • Thanks WanWizard. That's good enough for me. I'd been reading so much about "separating concerns" and "de-coupling" that I was afraid I was coupling my model and views too tightly. However, a view is a view of a model. There's no way around it. Whether I use a boatload of arrays or a single object, the data has to get there somehow. In previous releases I used arrays, but I still had to organize them in a meaningful way. That became a big headache on data-heavy pages. I did find one interesting point on an SO question (the 9/23/09 answer posted by elviejo). Passing the model object directly to the view (and not just its data) could allow the view to call model methods. For instance, if you had a design team that didn't know what they were doing (and you passed a Model_Parent instance as $parent with a method called delete)...
    <p><?php echo $parent->delete(); ?><p>
    
    Or, because the ORM is so beautiful it doesn't know any better, echoing what you think are properties could actually be doing database operations directly in your views. If for instance, you hadn't set/hydrated a Model_Parent's kid or puppy before passing the model to the view.
    <p><?php echo $parent->kid->puppy->name; ?><p>
    
    All in all, I'm not sure how big of a deal those two issues might be. At this point, I need to write it quicker more than I need to write it perfect. Objects it is!
  • I personally seldom pass ORM objects to views. I use the 'form' key in the models properties settings to define the generic definition of each column in the form (like the type of field, on forms or not, etc). I also have a method in my model to load the options array for the properties of type 'select'. Then, in my controllers I construct a fieldset instance using the add_model() method, creating a basic fieldset with all fields I want on the form. I pass this instance to the view. In the view, I customize the fieldset to the requirements of the view. Select the template used to generate the form, add extra fields or add attributes to existing fields, etc. For other fields (like a title or a username or some other single field) I use a Viewmodel, so I can abstract the fetching and processing of 'supporting' data from the controller code. It keeps your controller code clean, with only logic that deals with the request itself. For complex views, you can end up with 80% of your action code to be about retrieving all kinds of 'related' data, and only 20% with actually processing the request. For views that have to generate lists, I still pass array's to the view (the logic of which is in the model, the fetching of the data in the controller as it is part of the request, it's not 'related' data).

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion