lost on mvc basics: where to order data

I’m really struggling recently with understanding some basics of MVC.  I’m sold on the concept, but confused when it comes to asking hard questions like which kind of data manipulation goes into which box: model or controller.  Hopefully someone can help me out, because searching isn’t yielding much.  For background, I’m using PHP, CodeIgniter and PostgreSQL as my database.  That really shouldn’t matter much, but it helps to know what the Model is accessing (using SQL).

The basic question I have is, if you are running a complex query where you would have specific instructions on how to order the data, who does the ordering? the Model or the Controller?

If it’s the Model … then how do you pass in the order by variables into a function?  Do you have an argument that takes an ORDER BY variable that is inserted into your SQL statement?  Do you write specific functions in the Model that spit out the data in the possible orders that are available from the View?

If it’s the Controller … then how the heck do you order it?  Do you grab all the data, and then run ways to sort the arrays?  That seems extremely tedious.

I could go on ranting more, but I think I’ll leave my question as small as that for now.  Frankly, I’m stumped.

My situation I’m in right now is that I’m building reports which pull together data from multiple sources, and then need to organize them based on the most simplest ordering scheme which spans multiple columns.  That is, order by this first, then that, then the third column.  That’s all fine and good, but what about when the client wants to rearrange the data?  That’s where I get lost.

And I’m not looking for some out of the box solution like using JavaScript to rearrange data in the view dynamically.  I’m not interested in something like that.

Basically, my question is, if you are customizing data presented to the View, based on input from the client, where does the lifting go, and how do you get it in there?  Like I said, I’m lost.

6 comments on “lost on mvc basics: where to order data

  1. Jonathan

    Steve, MVC is really just a way of thinking and organizing your code. You can use it however you want. Pick a way that you like and run with it. Each framework will do it slightly differently.

    If it has to do with data and accessing it, any part of CRUD, put it in the model.

    I understand where you can get confused because the data is used in all parts of the code. A users uses the view to input or request data, the controller processes that request and sends what it needs to the model, the model stores and or retrieves that data and can order it or any other option you would like, then it gives the results back to the controller, the controller prepares it for the view, the view presents it to the user.

    I agree, it does take some wrapping around of the brain. 🙂 If you have not already, you should take the CakePHP blog tutorial. While it is using the CakePHP framework, it also does a good job of helping you get more familiar with MVC.

    Reply
  2. Bartosz Neuman

    For everyday PHP I use Zend Framework so my explanation may be a little biased towards its use. In my case it is the model that does the hard work while controller is as simple as possible).

    I would write something like this (in controller):
    // validate client input – prepare $where and $sort conditions
    $mapper = My_Model_Mapper();
    $this->view->sorted_models = $mapper->fetch($where_conditions, $sort_conditions);
    // and that’s all

    Mapper maps your data to your model. My_Model_Mapper::fetch() returns sorted array of My_Model which consists of __get and __set functions only (plus required variables). Mapper has information on different sources and does the hard work of combining them (and maybe sorting).

    If your all sources are from database, then you can put everything in one My_Model_Db and build appropriate SQL query. No need to read further. You can even omit My_Model_Mapper if you only read data (if you also modify it then you mapper will have also save and delete function). The mapper may also have different fetching functions.

    Assuming it has two different sources – a database (My_Model_Db) and file (My_Model_File) it can use their own fetch($where_conditions) functions to get data. To make it even prettier make My_Model_File and My_Model_Db implement My_Model_Interface 😉

    As to combining and sorting different sources I would use one of the following:

    1. Use My_Model_Mapper::fetch() to combine different sources and sort My_Model array after last source gave its data – less pretty.

    2. Create My_Model_Aggregate and make My_Model comparable. Write adding (My_Model_Aggregate::add(My_Model $new) and sorting function My_Model_Aggregate::sort($sort_conditions)* – more correct in terms of OO but you get another class.

    * You can sort as you add new objects too.

    Hope that makes sense and helps…

    Reply
  3. James Le Cuirot

    Unless your framework provides a good way to this then it’s generally down to personal taste. Some people prefer to stick almost everything in the model, leaving the controller code very thin. I’m somewhere in the middle. In Rails 2, you might do something like this in the controller.

    Post.all(:order => ‘created_at DESC’)

    SQL in the controller isn’t always desirable but that’s not too bad. There are alternatives though. Rails has something called named scopes.

    Model:
    named_scope :ordered, :order => ‘created_at DESC’

    Controller:
    Post.ordered

    You can even set a default scope so you don’t have to worry about the common cases.

    Model:
    default_scope :order => ‘created_at DESC’

    Controller:
    Post.all

    These last two examples aren’t very flexible if you want to allow sorting by different columns though. You could create different named scopes for each one but that seems little better than the first example. Since named scopes can take arguments, I personally create a “search_and_sort” method in my controller and accompanying named scope in my models that deals with common searching and sorting operations. It’s not very sexy but it quickly deals with the tediousness you would usually have to go through.

    Not trying to convert you to Rails btw. 😉 It’s just what I’m familiar with and the concepts still apply elsewhere.

    Reply
  4. mabi

    What I’m doing is passing an object that mimics a query (have sort, select fields, limit properties) to my model’s “search” function, which then turns it into real SQL and passes back the array of rows back to the controller.

    For complex queries (say GROUP BY or HAVING, or UNION queries) the model gets a function the controller can call.

    Re-Ordering in PHP is possible and quite fast. I use it on some <500 rows with asort/usort after selecting all candidates with a SQL-query. WFM, but YMMV 😉

    Reply
  5. Sander

    As you more or less already point out: you have to choose whether you want this to happen client-side or server-side. You’ve obviously made your choice…

    I use CakePHP a lot and they implement ordering in the model. If the ordering is based on user input you need to pass the input to the model through the controller.

    Out of curiousity, are you using a framework, or building something on your own?

    Reply
  6. thebigdog

    The model is where you would make the changes to the representation of the data. The controller takes the user input and the notifies or lets the model know about the changes in the data that then relates that change to the view. This would cause, for example, a refresh of the page. Any types of calculations should be done in the model (domain object).


    thebigdog

    Reply

Leave a Reply