views:

76

answers:

2

I am writing my first rails app. It needs to aggregate some data from multiple sites and for each site I have a unique way of getting the data (some provide RSS, some JSON, for some I scrape the HTML etc.). These will run on schedule, probably as a rake task from cron. It seems logical to store the sites and relevant information in a model, but I am not sure where to put unique data retrieval methods. Do I store method names in the model? Do I just name the methods the same as site name and call them that way? Basically, I need a way to read a list of sites and call appropriate method for each site. What is the Ruby on Rails way to do it?

A: 

Assuming you have a Site model, why not just add a new attribute to track the access method? You can do this by generating a new migration for the db alterations:

ruby script/generate migration add_access_method_to_sites # rails <= 2.3
ruby script/rails generate migration add_access_method_to_sites # rails >= 3.0
Damien Wilson
Well, I know how to add a field to a model, my question was if this was a good idea :)
Mad Wombat
Certainly. No reason to make things more complex than they need to be. While I can't say I'm an exemplary proponent of "The Rails Way", KISS has never failed me.
Damien Wilson
+1  A: 

I'd avoid storing method names in the database; that makes refactoring difficult and could lead to maddening behavior if you ever get invalid values in that column.

Instead, just store a format string column that's readable ("rss", "json", etc.). Then you can have a single method in your model like:

def pull_data
  case format
  when 'json'
    ...
  when 'rss'
    ...
  else
    raise 'Invalid format'
  end
end

If you want to break your data-getting logic into separate methods, you can call them from this pull_data method.

Tom
This is good, but I will end up with as many cases as I have sites. I am thinking of getting sites out of the database entirely, since I will not have more than a dozen of them and using a hashmap of some sort.
Mad Wombat