hagabaka (owner)

Revisions

gist: 215451 Download_button fork
public
Public Clone URL: git://gist.github.com/215451.git
Embed All Files: show embed
resources.rb #
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
require 'dm-core'
 
# An item is identified by a name, for example, Bread
class Item
  include DataMapper::Resource
 
  property :name, String, :key => true, :length => 100
  has n, :stacks
 
  # recipes which produce this item
  has n, :producing_recipes, :model => 'Recipe',
                                        :child_key => [:product_name]
 
  # recipes which use this item as an ingredient
  def consuming_recipes
    Recipe.all.select do |recipe|
      recipe.ingredients.any? do |ingredient|
        ingredient == self
      end
    end
  end
 
  # items which are products of consuming_recipes
  def derivatives
    consuming_recipes.map(&:product)
  end
 
  # items which are ingredients in producing_recipes
  def materials
    producing_recipes.inject do |items, recipe|
      items + recipe.ingredients
    end
  end
end
 
 
# A stack contains a number of the same item
class Stack
  include DataMapper::Resource
  property :id, Serial
  property :quantity, Integer
  belongs_to :item
  belongs_to :bag
end
 
# A bag contains a number of stacks
class Bag
  include DataMapper::Resource
  property :id, Serial
  property :type, Discriminator
  has n, :stacks
  has n, :items, :through => :stacks
 
  # retrieve the quantity of the given item in the bag, when 0 returns default
  def [](item, default=0)
    if stack = stacks.first('item.name' => item.name)
      stack.quantity
    else
      default
    end
  end
 
  # set the quantity of the given item in the bag
  def []=(item, quantity)
    if stack = stacks.first('item.name' => item.name)
      stack.quantity = quantity
    else
      stacks << Stack.new(:item_name => item.name, :quantity => quantity)
    end
  end
 
  # return a hash of item => quantity
  def quantities
    ret = {}
    stacks.each {|stack| ret[stack.item] = stack.quantity}
  end
end
 
# A recipe has one product item, and a few ingredient items each with a
# quantity, for example, Bread = 2 Flour + 1 Yeast + 1 Water
class Recipe < Bag
# include DataMapper::Resource
  belongs_to :product, :model => 'Item',
                                        :child_key => [:product_name]
  alias_method :ingredients, :items
end
 
# An identity is identified by an url, and has an inventory
class Identity
  include DataMapper::Resource
 
  property :url, String, :key => true, :length => 100
  has 1, :inventory
  has n, :items, :through => :inventory
end
 
# An inventory has a number of different items, and belongs to an identity
class Inventory < Bag
# include DataMapper::Resource
  belongs_to :identity
end