views:

642

answers:

4

So I'm working on a Rails app to get the feeling for the whole thing. I've got a Product model that's a standard ActiveRecord model. However, I also want to get some additional product info from Amazon ECS. So my complete model gets some of its info from the database and some from the web service. My question is, should I:

  1. Make two models a Product and a ProductAWS, and then tie them together at the controller level.

  2. Have the Product ActiveRecord model contain a ProductAWS object that does all the AWS stuff?

  3. Just add all the AWS functionality to my Product model.

  4. ???

A: 

You can use the composed_of relationship in ActiveRecord. You make a regular class with all the attributes that you manage through AWS and specify that your Product-class is composed_of this class. ActiveRecord will handle the delegation of the mapped attributes to and from this class.

See the documentation of composed_of

A: 

@Menno

What about using ActiveResource for the AWS-attributes class?

Hank Gay
Nah, I already have a client library.
BRH
A: 

As with most things: it depends. Each of your ideas have merit. If it were me, I'd start out this way:

  class Product < ActiveRecord::Base
     has_one :aws_item
  end 
  class AWSItem 
     belongs_to :product
  end

The key questions you want to ask yourself are:

Are you only going to be offering AWS ECS items, or will you have other products? If you'll have products that have nothing to do with Amazon, don't care about ASIN, etc, then a has_one could be the way to go. Or, even better, a polymorphic relationship to a :vendable interface so you can later plug in different extension types.

Is it just behavior that is different, or is the data going to be largely different too? Because you might want to consider:

class Product < ActiveRecord::Base
end 
class AWSItem < Product
  def do_amazon_stuff
    ... 
  end
end

How do you want the system to perform when Amazon ECS isn't available? Should it throw exceptions? Or should you rely on a local cached version of the catalog?

class Product < ActiveRecord::Base

end

class ItemFetcher < BackgrounDRb::Rails
   def do_work
      # .... Make a cached copy of your ECS catalog here. 
      # Copy the Amazon stuff into your local model
   end
end

Walk through these questions slowly and the answer will become clearer. If it doesn't, start prototyping it out. Good luck!

Pete
A: 

If you are retrieving data from two completely different sources (ActiveRecord on one hand and the Internet on the other), there are many benefits to keeping these as separate models. As the above poster wrote, Product has_one (or has_many) :aws_item.