views:

33

answers:

2

i would like to have your opinion in a project i am currently working on.

class Product
  has_many :orders
end

class Order
  attr_accessor :deliverable # to contain temporary data on how many items can be delivered for this order
  belongs_to :product
end

somehow i want to have

Order.all_deliverable

that will calculate the Product's quantity, subtract from list of Orders until the Product is empty or there is no more Order for this Product

to illustrate

  Product A, quantity: 20
  Product B, quantity: 0
  Order 1, require Product A, quantity: 12
  Order 2, require Product B, quantity: 10
  Order 3, require Product A, quantity: 100

so if i call Order.all_deliverable, it will give

Order 1, deliverable:12
Order 3, deliverable: 8 #(20-12)

i have been thinking on using named_scope, but i think the logic will be too complex to be put in a named_scope. Any suggestion?

the pseudo code for all_deliverable will be something like this: go to each orders find the remaining quantity for specific product deduct the product to max amount of order, if product is not enough, add the maximum product add to the order end

From what i read around in the web, named_scope deal mostly like find and have not many method calling and looping.

+1  A: 

I would use a class method. Named scopes are good for adding to the options list you normally pass to find. You should make them as simple as possible, so that callers can chain them together in a way that makes sense in a particular context, and that allow the scopes to be reused.

Design aside, I'm not sure this can work as a named scope anyway:

  • Scopes return proxies that delay loading from the database until you access them. I'm not sure how you'd do that when you're computing the records to return.
  • I'm not sure you can set non-column attributes from within a scope.
  • Even if the above two items don't apply, the delayed load of scopes means you build it now, but potentially don't load the data until some later time, when it could be stale.
Steve Madsen
thanks for the answer, i have to agree with using class method.partly because i cannot find an example about named_scope that manipulate variables inside, so in this case, i am returning an array of sales orders that can be delivered
Hadi
A: 

If you just want to manipulate things in a named scope, you can do it like this:

named_scope :foobar, lambda {

  # do anything here.

  # return hash with options for the named scope
  {
     :order => whatever,
     :limit => 50
  }
}

Be aware that Rails 3 deprecates long-used parts of activerecord.

x1a4