Class: Record
Constant Summary
AbstractRecord::CALLBACKS, AbstractRecord::FIELD_CALLBACKS, AbstractRecord::ORDERS
Instance Attribute Summary collapse
Attributes inherited from SiteRecord
#site
#changed, #errors, #stash, #typecast, #values
Instance Method Summary
collapse
-
#all_children ⇒ Object
All descendent children of this record, i.e children, grandchildren and so on.
-
#append_to_siblings ⇒ Object
-
#children_and_self ⇒ Object
All direct descendents of this record, and the record itself.
-
#collection ⇒ Object
-
#content ⇒ Object
—————————————- Rendering —————————————-.
-
#create_eigenmodel ⇒ Object
-
#create_mixin_instances(values) ⇒ Object
-
#default_values ⇒ Object
-
#delegate_mixins ⇒ Object
-
#destroy_children ⇒ Object
-
#field_sections ⇒ Object
-
#fields ⇒ Object
—————————————- Modelling —————————————-.
-
#first_non_blank_response_to(message) ⇒ Object
-
#first_parent(type, exact = false) ⇒ Object
Returns the first parent which is an instance of type.
-
#first_response_to(message) ⇒ Object
Finds the first parent which can respond to ‘message’ and returns the result.
-
#get_binding ⇒ Object
-
#has_eigenmodel? ⇒ Boolean
-
#initialize(model, site, values = {}, new_record = true) ⇒ Record
constructor
A new instance of Record.
-
#insert_in_siblings(new_index) ⇒ Object
FIXME: these need to be atomic ops over the whole set of children FIXME: it also seems weird to perform increments on siblings, but leave the index change to this record unchanged.
-
#inspect_hash ⇒ Object
-
#load_model(model, values) ⇒ Object
-
#model_name ⇒ Object
-
#parent?(record) ⇒ Boolean
True if record is a parent (ancestor) of this record.
-
#parents ⇒ Object
An array of parent records all the way back to a root record.
-
#perform_reload(params) ⇒ Object
-
#prepare_reload_params ⇒ Object
-
#remove_eigenmodel ⇒ Object
-
#remove_from_siblings ⇒ Object
-
#root? ⇒ Boolean
True if this record has no parent.
-
#run_record_after_create_callbacks ⇒ Object
-
#run_record_after_destroy_callbacks ⇒ Object
-
#run_record_after_save_callbacks ⇒ Object
-
#run_record_after_update_callbacks ⇒ Object
-
#run_record_after_validation_callbacks ⇒ Object
-
#run_record_before_create_callbacks ⇒ Object
-
#run_record_before_destroy_callbacks ⇒ Object
-
#run_record_before_save_callbacks ⇒ Object
-
#run_record_before_update_callbacks ⇒ Object
-
#run_record_before_validation_callbacks ⇒ Object
-
#set_content(content) ⇒ Object
-
#siblings ⇒ Object
Siblings of this record (other records with the same parent).
-
#to_str ⇒ Object
-
#update_search_keywords ⇒ Object
-
#user_allowed_to?(user, action) ⇒ Boolean
—————————————- Permissions —————————————-.
-
#user_allowed_to_create?(user) ⇒ Boolean
-
#user_allowed_to_delete?(user) ⇒ Boolean
-
#user_allowed_to_update?(user) ⇒ Boolean
-
#user_allowed_to_view?(user) ⇒ Boolean
Methods inherited from SiteRecord
#site_id
Methods included from SiteModel
#load, #scoped, #scoped_for
Methods included from MongoModel
#load, #scoped
#embed_many, #embed_one, #field, #many, #modify_field, #one, #remove_field
Methods inherited from MongoRecord
#id, #increment!, #load_from_mongo, #load_mongo_document, #perform_destroy, #perform_save, #set_id
#changed!, #changed?, #clear_key, #destroy, #destroyed?, #eql?, #errors?, #field, #field?, #field_was, #from_json, #get, #get_meta, #get_raw, #hash, #id, #increment!, inherited, #inspect, #inspect_value, #method_missing, #new?, #present?, #reload, #save, #save_without_validation, #search_terms, #set, #set_meta, #set_raw, #to_json, #trigger_field_callback, #update, #valid?
Constructor Details
#initialize(model, site, values = {}, new_record = true) ⇒ Record
Returns a new instance of Record.
13
14
15
16
17
18
19
20
21
22
23
24
25
|
# File 'lib/yodel/models/core/record/record.rb', line 13
def initialize(model, site, values={}, new_record=true)
@model_record = model
@site = site
@model = load_model(model, values)
@mixins = create_mixin_instances(values)
super(site, values, new_record)
delegate_mixins
end
|
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
in the class AbstractRecord
Instance Attribute Details
#mixins ⇒ Object
Returns the value of attribute mixins.
10
11
12
|
# File 'lib/yodel/models/core/record/record.rb', line 10
def mixins
@mixins
end
|
#model ⇒ Object
Returns the value of attribute model.
10
11
12
|
# File 'lib/yodel/models/core/record/record.rb', line 10
def model
@model
end
|
#model_record ⇒ Object
Returns the value of attribute model_record.
10
11
12
|
# File 'lib/yodel/models/core/record/record.rb', line 10
def model_record
@model_record
end
|
#real_record ⇒ Object
reference to the ‘real’ record if this object is a mixin
11
12
13
|
# File 'lib/yodel/models/core/record/record.rb', line 11
def real_record
@real_record
end
|
Instance Method Details
#all_children ⇒ Object
All descendent children of this record, i.e children, grandchildren and so on.
295
296
297
|
# File 'lib/yodel/models/core/record/record.rb', line 295
def all_children
[self, children.collect(&:all_children)].flatten
end
|
#append_to_siblings ⇒ Object
248
249
250
251
252
|
# File 'lib/yodel/models/core/record/record.rb', line 248
def append_to_siblings
return unless new?
highest_index = siblings.last.try(:index) || 0
self.index = highest_index + 1
end
|
#children_and_self ⇒ Object
All direct descendents of this record, and the record itself
290
291
292
|
# File 'lib/yodel/models/core/record/record.rb', line 290
def children_and_self
[self, children].flatten
end
|
#collection ⇒ Object
35
36
37
|
# File 'lib/yodel/models/core/record/record.rb', line 35
def collection
Record.collection
end
|
#content ⇒ Object
357
358
359
|
# File 'lib/yodel/models/core/record/record.rb', line 357
def content
@content ||= get('content')
end
|
#create_eigenmodel ⇒ Object
103
104
105
106
107
108
109
|
# File 'lib/yodel/models/core/record/record.rb', line 103
def create_eigenmodel
return eigenmodel if eigenmodel?
new_eigenmodel = model.create_model("#{id}_eigenmodel")
self.eigenmodel = new_eigenmodel
@model = new_eigenmodel
save
end
|
#create_mixin_instances(values) ⇒ Object
125
126
127
128
129
130
|
# File 'lib/yodel/models/core/record/record.rb', line 125
def create_mixin_instances(values)
return [] if @model.nil?
@model.mixins.collect do |mixin_model|
mixin_model.record_class.new(mixin_model, site, values)
end.compact
end
|
#default_values ⇒ Object
31
32
33
|
# File 'lib/yodel/models/core/record/record.rb', line 31
def default_values
super.merge({'model' => model.id})
end
|
#delegate_mixins ⇒ Object
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
|
# File 'lib/yodel/models/core/record/record.rb', line 132
def delegate_mixins
extend SingleForwardable
ancestors = self.class.ancestors
included_classes = []
mixins.each_with_index do |mixin, index|
%w{@model @new @site @values @typecast @changed @errors @stash}.each do |var|
mixin.instance_variable_set(var, instance_variable_get(var))
end
mixin.extend SingleForwardable
mixin.real_record = self
mixin.def_delegators :@real_record, :save, :save_without_validation, :destroy, :update,
:reload, :fields
mixin.class.ancestors.each do |klass|
break if ancestors.include?(klass)
next if included_classes.include?(klass)
def_delegators "@mixins[#{index}]", *klass.instance_methods(false)
included_classes << klass
end
end
end
|
#destroy_children ⇒ Object
274
275
276
|
# File 'lib/yodel/models/core/record/record.rb', line 274
def destroy_children
children.each(&:destroy)
end
|
#field_sections ⇒ Object
80
81
82
83
84
85
86
87
88
89
90
|
# File 'lib/yodel/models/core/record/record.rb', line 80
def field_sections
@sections ||= begin
keyed_sections = Hash.new do |hash, key|
hash[key] = Section.new(key)
end
fields.each do |name, field|
keyed_sections[field.section] << field
end
keyed_sections
end
end
|
#fields ⇒ Object
76
77
78
|
# File 'lib/yodel/models/core/record/record.rb', line 76
def fields
@fields ||= @model.all_record_fields
end
|
#first_non_blank_response_to(message) ⇒ Object
342
343
344
345
346
347
348
349
350
351
|
# File 'lib/yodel/models/core/record/record.rb', line 342
def first_non_blank_response_to(message)
message = message.to_s
parents.find do |record|
if record.respond_to?(message) || record.fields.keys.include?(message)
value = record.send(message)
return value unless value.blank?
end
end
''
end
|
#first_parent(type, exact = false) ⇒ Object
Returns the first parent which is an instance of type
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
|
# File 'lib/yodel/models/core/record/record.rb', line 316
def first_parent(type, exact=false)
model = site.model_by_plural_name(type.to_s.downcase.pluralize)
if exact
match = parents.find {|record| record.model == model}
else
match = parents.find {|record| record.model.parents_and_mixins.include?(model)}
end
if block_given?
yield match
else
match
end
end
|
#first_response_to(message) ⇒ Object
Finds the first parent which can respond to ‘message’ and returns the result. Will return nil if no parents response to the message, however, keep in mind that nil may be a valid response to this message.
335
336
337
338
339
340
|
# File 'lib/yodel/models/core/record/record.rb', line 335
def first_response_to(message)
message = message.to_s
parents.find do |record|
return record.send(message) if record.respond_to?(message) || record.fields.keys.include?(message)
end
end
|
#get_binding ⇒ Object
365
366
367
|
# File 'lib/yodel/models/core/record/record.rb', line 365
def get_binding
binding
end
|
#has_eigenmodel? ⇒ Boolean
117
118
119
|
# File 'lib/yodel/models/core/record/record.rb', line 117
def has_eigenmodel?
self.eigenmodel != nil
end
|
#insert_in_siblings(new_index) ⇒ Object
FIXME: these need to be atomic ops over the whole set of children FIXME: it also seems weird to perform increments on siblings, but leave the index change to this record unchanged
256
257
258
259
260
261
262
263
264
|
# File 'lib/yodel/models/core/record/record.rb', line 256
def insert_in_siblings(new_index)
original_parent = self.parent
remove_from_siblings if index
self.parent = original_parent
siblings.where(:index.gte => new_index).each do |sibling|
sibling.increment!(:index)
end
self.index = new_index
end
|
#inspect_hash ⇒ Object
92
93
94
|
# File 'lib/yodel/models/core/record/record.rb', line 92
def inspect_hash
{model: model, parent: parent, index: index}.merge(super)
end
|
#load_model(model, values) ⇒ Object
96
97
98
99
100
101
|
# File 'lib/yodel/models/core/record/record.rb', line 96
def load_model(model, values)
return model if values['eigenmodel'].nil?
eigenmodel = site.models.find(values['eigenmodel'])
values['eigenmodel'] = nil if eigenmodel.nil?
eigenmodel || model
end
|
#model_name ⇒ Object
121
122
123
|
# File 'lib/yodel/models/core/record/record.rb', line 121
def model_name
has_eigenmodel? ? self.eigenmodel.parent.name : self.model_record.name
end
|
#parent?(record) ⇒ Boolean
True if record is a parent (ancestor) of this record
311
312
313
|
# File 'lib/yodel/models/core/record/record.rb', line 311
def parent?(record)
parents.include?(record)
end
|
#parents ⇒ Object
An array of parent records all the way back to a root record. e.g calling on a page two levels deep would return: [page, parent, root]
301
302
303
|
# File 'lib/yodel/models/core/record/record.rb', line 301
def parents
[self, self.parent.try(:parents)].flatten.compact
end
|
39
40
41
42
|
# File 'lib/yodel/models/core/record/record.rb', line 39
def perform_reload(params)
document = load_mongo_document(_id: params[:id])
initialize(params[:model], params[:site], document)
end
|
#prepare_reload_params ⇒ Object
44
45
46
|
# File 'lib/yodel/models/core/record/record.rb', line 44
def prepare_reload_params
super.tap {|vals| vals[:model] = @model}
end
|
#remove_eigenmodel ⇒ Object
111
112
113
114
115
|
# File 'lib/yodel/models/core/record/record.rb', line 111
def remove_eigenmodel
eigenmodel.destroy if eigenmodel?
self.eigenmodel = nil
save
end
|
#remove_from_siblings ⇒ Object
266
267
268
269
270
271
272
|
# File 'lib/yodel/models/core/record/record.rb', line 266
def remove_from_siblings
siblings.where(:index.gte => index).each do |sibling|
sibling.increment!(:index, -1)
end
self.index = nil
self.parent = nil
end
|
#root? ⇒ Boolean
True if this record has no parent
306
307
308
|
# File 'lib/yodel/models/core/record/record.rb', line 306
def root?
parent.nil?
end
|
#run_record_after_create_callbacks ⇒ Object
214
215
216
|
# File 'lib/yodel/models/core/record/record.rb', line 214
def run_record_after_create_callbacks
model.run_record_after_create_callbacks(self)
end
|
#run_record_after_destroy_callbacks ⇒ Object
234
235
236
|
# File 'lib/yodel/models/core/record/record.rb', line 234
def run_record_after_destroy_callbacks
model.run_record_after_destroy_callbacks(self)
end
|
#run_record_after_save_callbacks ⇒ Object
204
205
206
|
# File 'lib/yodel/models/core/record/record.rb', line 204
def run_record_after_save_callbacks
model.run_record_after_save_callbacks(self)
end
|
#run_record_after_update_callbacks ⇒ Object
224
225
226
|
# File 'lib/yodel/models/core/record/record.rb', line 224
def run_record_after_update_callbacks
model.run_record_after_update_callbacks(self)
end
|
#run_record_after_validation_callbacks ⇒ Object
194
195
196
|
# File 'lib/yodel/models/core/record/record.rb', line 194
def run_record_after_validation_callbacks
model.run_record_after_validation_callbacks(self)
end
|
#run_record_before_create_callbacks ⇒ Object
209
210
211
|
# File 'lib/yodel/models/core/record/record.rb', line 209
def run_record_before_create_callbacks
model.run_record_before_create_callbacks(self)
end
|
#run_record_before_destroy_callbacks ⇒ Object
229
230
231
|
# File 'lib/yodel/models/core/record/record.rb', line 229
def run_record_before_destroy_callbacks
model.run_record_before_destroy_callbacks(self)
end
|
#run_record_before_save_callbacks ⇒ Object
199
200
201
|
# File 'lib/yodel/models/core/record/record.rb', line 199
def run_record_before_save_callbacks
model.run_record_before_save_callbacks(self)
end
|
#run_record_before_update_callbacks ⇒ Object
219
220
221
|
# File 'lib/yodel/models/core/record/record.rb', line 219
def run_record_before_update_callbacks
model.run_record_before_update_callbacks(self)
end
|
#run_record_before_validation_callbacks ⇒ Object
189
190
191
|
# File 'lib/yodel/models/core/record/record.rb', line 189
def run_record_before_validation_callbacks
model.run_record_before_validation_callbacks(self)
end
|
#set_content(content) ⇒ Object
361
362
363
|
# File 'lib/yodel/models/core/record/record.rb', line 361
def set_content(content)
@content = content
end
|
#siblings ⇒ Object
Siblings of this record (other records with the same parent)
279
280
281
282
283
284
285
286
287
|
# File 'lib/yodel/models/core/record/record.rb', line 279
def siblings
unless parent.nil?
model.unscoped.where(:parent => parent.try(:id), :_id.ne => id).order('index asc')
else
model.unscoped.where(:nonexistant_field => 'true')
end
end
|
#to_str ⇒ Object
27
28
29
|
# File 'lib/yodel/models/core/record/record.rb', line 27
def to_str
"#<#{model_record.name}: #{id}>"
end
|
#update_search_keywords ⇒ Object
374
375
376
377
|
# File 'lib/yodel/models/core/record/record.rb', line 374
def update_search_keywords
return unless model.searchable?
self.search_keywords = search_terms
end
|
#user_allowed_to?(user, action) ⇒ Boolean
52
53
54
|
# File 'lib/yodel/models/core/record/record.rb', line 52
def user_allowed_to?(user, action)
model.user_allowed_to?(user, action, self)
end
|
#user_allowed_to_create?(user) ⇒ Boolean
68
69
70
|
# File 'lib/yodel/models/core/record/record.rb', line 68
def user_allowed_to_create?(user)
model.user_allowed_to?(user, :create, self)
end
|
#user_allowed_to_delete?(user) ⇒ Boolean
64
65
66
|
# File 'lib/yodel/models/core/record/record.rb', line 64
def user_allowed_to_delete?(user)
model.user_allowed_to?(user, :delete, self)
end
|
#user_allowed_to_update?(user) ⇒ Boolean
60
61
62
|
# File 'lib/yodel/models/core/record/record.rb', line 60
def user_allowed_to_update?(user)
model.user_allowed_to?(user, :update, self)
end
|
#user_allowed_to_view?(user) ⇒ Boolean
56
57
58
|
# File 'lib/yodel/models/core/record/record.rb', line 56
def user_allowed_to_view?(user)
model.user_allowed_to?(user, :view, self)
end
|