views:

28

answers:

1

This is a complicated question with many possible answers, so I'll break down my situation into simple bullet points to help narrow down the solution:

My Rails App Has the Following 'Objects'

  1. Author
  2. Feed
  3. Update
  4. FeedTypes

The Objects are Related Like So:

  1. Authors can have 1 or more Feeds
  2. Feeds can have one or more Updates
  3. A Feed has one feedType

Example Setup:

  • Author: Levi Hackwith
  • Feed: view-source:http://www.twitter.com/statuses/user_timeline/opnsrce.xml
  • FeedType: Twitter
  • Update: The tweets inside the Feed

My problem and My Questions:

Problem:

I need to parse the above-mentioned feed and store each tweet in the updates table. To parse the feed, I was thinking of writing a custom Feed class which would get inherited by TwitterFeed, FacebookFeed, TumblrFeed, etc.

However, I'm not sure if this is the 'Best Practice' for solving this kind of problem.

Questions:

  1. When is it appropriate to develop a custom class to perform an action in RoR (as opposed to going through the Model or Controller)?
  2. If this situation does not call for a custom class, which element should I apply the parsing logic to? The model or the controller?
  3. If this is an appropriate situation for a custom class, where in my rails application should I store it (in other words, what's the right 'convention')?
+1  A: 

You are probably going to have a background task invoked from time-to-time to check all the feeds, fetch new updates and store those in database. This task is completely separate from controllers and it should be possible to invoke it without any controller logic.

Your abstraction looks fine. You can further have something like XmlFeed < Feed if several feeds share a common XML structure.

1) Controllers should talk to database/models and pass relevant data to the view to render. Everything else should be either in a model, helper or library.

2) Are you asking where the parsing logic belongs to? In MVC, I think this would belong under the Model and/or a helper class, but definitely not the controller.. it's not its responsibility.

3) Classes holding data go into app/models. Classes that have nothing to do with holding data, go into the lib directory.

randomguy
What about having a 'loadUpdates' or 'parse' method inside of the feed model? Is that legit? I ask because whenever the main page is loaded, all updates for a given feed are deleted and then re-inserted regardless of how 'new' they are.
Levi Hackwith
Do you really want to keep the user waiting while the code fetches the feed (which might or not be available), parses it and renders it? This could take several seconds. IMHO, a better approach would be to invoke the task every 5 minutes (or more often if you want to keep the feeds more fresh, but this will consume more CPU and bandwidth). `loadUpdates` fits and it can be in `Feed`, since this is something that all feeds share. However, you should use lowercased_and_underscored instead.. ie. `load_updates`. This is ruby naming convention for method names.
randomguy
If you still prefer to update whenever user load the main page, then simply call `load_updates` from the main page action. You don't need `updates` table then, since you don't access that data. Return a collection of updates from `load_updates`.
randomguy