Class: Orange::Carton

Inherits:
Object show all
Extended by:
ClassInheritableAttributes
Defined in:
lib/orange-core/carton.rb

Overview

Orange::Carton is the main model class for Orange. It’s based on Datamapper. In addition to handling the database interactions, the carton keeps track of declared properties, which is used to create scaffolds.

All subclasses should start by declaring the “id” attribute. All models are assumed to have an id attribute by most everything else, so it’s a good idea to have one. Also, we use this to tie in initialization before using the other dsl-ish methods (since these other methods are class level and would happen before initialize ever gets called)

Orange::Carton adds many shortcut methods for adding various datatypes to the model in a more declarative style (‘id` vs `property :id, Serial`)

For classes that don’t need anything but scaffolding, there’s the as_resource method, which automatically creates a scaffolding resource for the model.

A model that doesn’t need scaffolded at all could optionally forgo the carton class and just include DataMapper::Resource. All carton methods are to improve scaffolding capability.

Constant Summary collapse

SCAFFOLD_OPTIONS =
[:display_name, :levels, :related_to, :wrap_tag]

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ClassInheritableAttributes

cattr_accessor, cattr_reader, cattr_writer, eval_in_accessor_module, fetch_value, store_value

Class Method Details

.add_scaffold(name, type, dm_type, opts) ⇒ Object



90
91
92
93
94
# File 'lib/orange-core/carton.rb', line 90

def self.add_scaffold(name, type, dm_type, opts)
  self.scaffold_properties << {:name => name, :type => type, :levels => @levels, :lazy => false}.merge(opts) if @levels || opts.has_key?(:levels)
  opts = opts.delete_if{|k,v| SCAFFOLD_OPTIONS.include?(k)} # DataMapper doesn't like arbitrary opts
  self.property(name, dm_type, opts)
end

.admin(&block) ⇒ Object

Helper to wrap properties into admin level



70
71
72
73
74
# File 'lib/orange-core/carton.rb', line 70

def self.admin(&block)
  @levels = [:admin, :orange]
  instance_eval(&block)
  @levels = false
end

.admin_property(name, type, opts = {}) ⇒ Object

For more generic cases, use same syntax as DataMapper does. The difference is that this will make it an admin property.



202
203
204
205
206
# File 'lib/orange-core/carton.rb', line 202

def self.admin_property(name, type, opts = {})
  my_type = type.to_s.downcase.to_sym
  opts[:levels] = [:admin, :orange]
  add_scaffold(name, my_type, type, opts)
end

.as_resourceObject

Declares a ModelResource subclass that scaffolds this carton The Subclass will have the name of the carton followed by “_Resource”



31
32
33
34
35
36
37
38
# File 'lib/orange-core/carton.rb', line 31

def self.as_resource
  name = self.to_s
  eval <<-HEREDOC
  class ::#{name}_Resource < Orange::ModelResource
    use #{name}
  end
  HEREDOC
end

.belongs(name, model, opts = {}) ⇒ Object

Define a helper for belongs_to stuff



149
150
151
152
153
# File 'lib/orange-core/carton.rb', line 149

def self.belongs(name, model, opts = {})
  relationship_scaffold(name, :belongs, opts.with_defaults(:related_to => model))
  opts = opts.delete_if{|k,v| SCAFFOLD_OPTIONS.include?(k)} # DataMapper doesn't like arbitrary opts
  self.belongs_to(name, model, opts)
end

.boolean(name, opts = {}) ⇒ Object

Define a helper for boolean type database stuff Show in a context if wrapped in one of the helpers



138
139
140
# File 'lib/orange-core/carton.rb', line 138

def self.boolean(name, opts = {})
  add_scaffold(name, :boolean, DataMapper::Property::Boolean, opts.with_defaults(:lazy => true))
end

.date(name, opts = {}) ⇒ Object

Define a helper for title type database stuff Show in a context if wrapped in one of the helpers



114
115
116
# File 'lib/orange-core/carton.rb', line 114

def self.date(name, opts = {})
  add_scaffold(name, :date, Date, opts)
end

.datetime(name, opts = {}) ⇒ Object

Define a helper for title type database stuff Show in a context if wrapped in one of the helpers



108
109
110
# File 'lib/orange-core/carton.rb', line 108

def self.datetime(name, opts = {})
  add_scaffold(name, :datetime, DateTime, opts)
end

.expose(name, opts = {}) ⇒ Object

Define a helper for type database stuff Show in a context if wrapped in one of the helpers



182
183
184
# File 'lib/orange-core/carton.rb', line 182

def self.expose(name, opts = {})
  self.scaffold_properties << {:name => name, :type => :text, :levels => @levels, :opts => opts} if @levels
end

.form_props(context = :live, mode = :any) ⇒ Object

Return properties that should be shown for a given context



53
54
55
56
# File 'lib/orange-core/carton.rb', line 53

def self.form_props(context = :live, mode = :any)
  self.scaffold_properties ||= []
  self.scaffold_properties.select{|p| should_use?(p, context, mode)  }
end

.front(&block) ⇒ Object

Helper to wrap properties into front level



84
85
86
87
88
# File 'lib/orange-core/carton.rb', line 84

def self.front(&block)
  @levels = [:live, :admin, :orange]
  instance_eval(&block)
  @levels = false
end

.front_property(name, type, opts = {}) ⇒ Object

For more generic cases, use same syntax as DataMapper does. The difference is that this will make it a front property.



210
211
212
213
214
# File 'lib/orange-core/carton.rb', line 210

def self.front_property(name, type, opts = {})
  my_type = type.to_s.downcase.to_sym
  opts[:levels] = [:live, :admin, :orange]
  add_scaffold(name, my_type, type, opts)
end

.fulltext(name, opts = {}) ⇒ Object

Define a helper for fulltext type database stuff Show in a context if wrapped in one of the helpers



132
133
134
# File 'lib/orange-core/carton.rb', line 132

def self.fulltext(name, opts = {})
  add_scaffold(name, :fulltext, DataMapper::Property::Text, opts.with_defaults(:lazy => true))
end

.has_and_belongs_to_many(name, model, opts = {}) ⇒ Object

Define a helper for has_many



172
173
174
175
176
177
# File 'lib/orange-core/carton.rb', line 172

def self.has_and_belongs_to_many(name, model, opts = {})
  relationship_scaffold(name, :has_and_belongs_to_many, opts.with_defaults(:related_to => model))
  opts = opts.delete_if{|k,v| SCAFFOLD_OPTIONS.include?(k)} # DataMapper doesn't like arbitrary opts
  opts.with_defaults!({:through => DataMapper::Resource})
  self.has(n, name, model, opts)
end

.has_many(name, model, opts = {}) ⇒ Object

Define a helper for has_many



164
165
166
167
168
# File 'lib/orange-core/carton.rb', line 164

def self.has_many(name, model, opts = {})
  relationship_scaffold(name, :has_many, opts.with_defaults(:related_to => model))
  opts = opts.delete_if{|k,v| SCAFFOLD_OPTIONS.include?(k)} # DataMapper doesn't like arbitrary opts
  self.has(n, name, model, opts)
end

.has_one(name, model, opts = {}) ⇒ Object

Define a helper for has_one



156
157
158
159
160
# File 'lib/orange-core/carton.rb', line 156

def self.has_one(name, model, opts = {})
  relationship_scaffold(name, :has_one, opts.with_defaults(:related_to => model))
  opts = opts.delete_if{|k,v| SCAFFOLD_OPTIONS.include?(k)} # DataMapper doesn't like arbitrary opts
  self.has(1, name, model, opts)
end

.idObject

Do setup of object and declare an id



41
42
43
44
45
46
# File 'lib/orange-core/carton.rb', line 41

def self.id
  include DataMapper::Resource
  property(:id, DataMapper::Property::Serial)
  self.scaffold_properties ||= []
  self.init
end

.initObject

Stub init method



49
50
# File 'lib/orange-core/carton.rb', line 49

def self.init
end

.number(name, opts = {}) ⇒ Object

Show in a context if wrapped in one of the helpers



126
127
128
# File 'lib/orange-core/carton.rb', line 126

def self.number(name, opts = {})
  add_scaffold(name, :number, Float, opts)
end

.orange(&block) ⇒ Object

Helper to wrap properties into orange level



77
78
79
80
81
# File 'lib/orange-core/carton.rb', line 77

def self.orange(&block)
  @levels = [:orange]
  instance_eval(&block)
  @levels = false
end

.orange_property(name, type, opts = {}) ⇒ Object

For more generic cases, use same syntax as DataMapper does. The difference is that this will make it an orange property.



218
219
220
221
222
# File 'lib/orange-core/carton.rb', line 218

def self.orange_property(name, type, opts = {})
  my_type = type.to_s.downcase.to_sym
  opts[:levels] = [:orange]
  add_scaffold(name, my_type, type, opts)
end

.relationship_scaffold(name, type, opts) ⇒ Object



96
97
98
# File 'lib/orange-core/carton.rb', line 96

def self.relationship_scaffold(name, type, opts)
  self.scaffold_properties << {:name => name, :type => type, :levels => @levels, :lazy => false, :relationship => true}.merge(opts) if @levels || opts.has_key?(:levels)
end

.scaffold_property(name, type, opts = {}) ⇒ Object

Override DataMapper to include context sensitivity (as set by helpers)



194
195
196
197
# File 'lib/orange-core/carton.rb', line 194

def self.scaffold_property(name, type, opts = {})
  my_type = type.to_s.downcase.to_sym
  add_scaffold(name, my_type, type, opts)
end

.should_use?(property, context, mode = :any) ⇒ Boolean

Returns:

  • (Boolean)


58
59
60
61
62
63
64
65
66
67
# File 'lib/orange-core/carton.rb', line 58

def self.should_use?(property, context, mode = :any )
  if(mode == :any || mode.blank?)
    property[:levels].include?(context)
  else
    (property[:levels].include?(context) && 
      (property[:lazy] == false || 
       property[:lazy] == mode || 
       (property[:lazy].is_a?(Array) && property[:lazy].include?(mode))))
  end
end

.string(name, opts = {}) ⇒ Object

Define a helper for input type=“text” type database stuff Show in a context if wrapped in one of the helpers



189
190
191
# File 'lib/orange-core/carton.rb', line 189

def self.string(name, opts = {})
  self.text(name, opts)
end

.text(name, opts = {}) ⇒ Object

Define a helper for input type=“text” type database stuff Show in a context if wrapped in one of the helpers



144
145
146
# File 'lib/orange-core/carton.rb', line 144

def self.text(name, opts = {})
  add_scaffold(name, :text, String, opts)
end

.time(name, opts = {}) ⇒ Object

Define a helper for title type database stuff Show in a context if wrapped in one of the helpers



120
121
122
# File 'lib/orange-core/carton.rb', line 120

def self.time(name, opts = {})
  add_scaffold(name, :time, Time, opts)
end

.title(name, opts = {}) ⇒ Object

Define a helper for title type database stuff Show in a context if wrapped in one of the helpers



102
103
104
# File 'lib/orange-core/carton.rb', line 102

def self.title(name, opts = {})
  add_scaffold(name, :title, String, opts)
end

Instance Method Details

#scaffold_nameObject



224
225
226
227
228
229
230
# File 'lib/orange-core/carton.rb', line 224

def scaffold_name
  titles = self.class.scaffold_properties.select{|p| p[:type] == :title}
  return __send__(titles.first[:name]) if(self.respond_to?(titles.first[:name]))
  return title if(self.respond_to?(:title)) 
  return name if(self.respond_to?(:name))
  return "#{self.class.to_s} ##{id}"
end

#to_sObject



232
233
234
235
236
# File 'lib/orange-core/carton.rb', line 232

def to_s
  <<-DOC
  {"class": "#{self.class.to_s}", "id": "#{self.id}"}
  DOC
end