views:

46

answers:

4

Suppose there is a call to get Analytics data from a third party or through our cache data on a server, for the "most popular items", and we show these items' names on all of our pages, should we put this code in Model, Controller, or View (Helper) component?

Maybe it is not strictly Model, because it is not directly in our data store.

Maybe it is Controller... should it be in the "general controller", such as in app/controller/application.rb to be sharable in all views? What if it is obtained in the controller code, but 1 month later, another person follow a new spec and remove the display of it on a view, then the code probably stay at the controller and nobody will remove it.

If it is in the helper... then what if in other part of the code, the controller need to get that data and store it in @popular? Also, aren't helpers suppose to help render data by putting repeated task in methods? So helpers shouldn't do so much data fetching logic.

Where is the code most properly placed?

+1  A: 

Although I use .net mvc I think the same principles can apply.

So that being said here is what I usually have:

Controller > Service > Repository code.

So in this case you would have an Analytics service that handles the request and may make calls to third party or may call a repository layer (maybe both) that retrieves data from database. But this way all calls go through the same service. Plus removes any knowledge of how data is retrieved. In fact I had a similar situation one time where we were using a mail client and pulling in some of the analytics from their server and some from our database. All of that was hidden in the service layer so all that was returned was a model that could be used however it was seen fit.

Then all controllers who need it can share. In the view I would then have a helper that displays that data. Again anyone who wants can call the helper and pass the model data in required for that helper. This allows you to apply DRY principle.

Again this works for me. YMMV

spinon
+1  A: 

(Disclaimer: this is coming from a Django background, my apologies if the terms or methodology don't directly translate into the MVC framework that you're using.)

My design process would basically go as follows:

I know that I wouldn't want to have to re-calculate the Analytics data for every page hit, so my choice is between just relying on a cache or using a cache in tandem with storing the temporary results in a database. I'd personally go for the latter method.

So I'd setup a Model to handle storing a subset of the Analytics data for the task at hand, saving the "most popular items" in your case. I would then create an automated task (say in cron, or in Django I would use Celery) to aggregate that data on a regular basis, perhaps at midnight every night.

Then I would just write some helpers to quickly query that aggregated data and display it in my template (the View in other frameworks).

In summary, I'd use a combination of the Model and View in the MVC paradigm. I don't see any reason to really involve the Controller in this process.

Pewpewarrows
+1  A: 

I would like to suggest creating a google_api datasource. A quick google search should pop up a few of them that seem half finished to get a start with.

Use the GAPI class from google code from within the datasource to fetch data from google and format the results into something you can use.

Then you can setup a model for each metric you want to track. IE. class GoogleAnalyticsKeyword, GoogleAnalyticsAdWordCampaign etc. These models can be set to use your custom datasource. From the model you can do caching, validation etc on the data.

Then simply reference the models in the uses array in a controller. Either app_controller or dashboard_controller etc. Then just query the models from the controller you need the data to be available from.

http://code.google.com/p/gapi-google-analytics-php-interface/

http://github.com/msadouni/cakephp-plugin-google-analytics

Abba Bryant
A: 

If you want to place it either Model, View or Controller, I would put it in a Model, because Models are responsible for CRUD actions, and retrieving a list of the most popular items is part of that.

I don't think it has to be in your data storage to count as a Model.

My 2 cents.

tilman