Module: Fragmentary::Fragment
- Defined in:
- lib/fragmentary/fragment.rb
Defined Under Namespace
Modules: ClassMethods, NeedsKey, NeedsRecordId, NeedsUserId, NeedsUserType
Class Method Summary
collapse
Instance Method Summary
collapse
Class Method Details
.base_class ⇒ Object
5
6
7
|
# File 'lib/fragmentary/fragment.rb', line 5
def self.base_class
@base_class
end
|
.included(base) ⇒ Object
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
|
# File 'lib/fragmentary/fragment.rb', line 9
def self.included(base)
@base_class = base
base.class_eval do
include ActionView::Helpers::CacheHelper
belongs_to :parent, :class_name => name
belongs_to :root, :class_name => name
has_many :children, :class_name => name, :foreign_key => :parent_id, :dependent => :destroy
belongs_to :user
after_commit :touch_parent, :on => [:update, :destroy]
attr_accessor :indexed_children
self.cache_timestamp_format = :usec
end
base.instance_eval do
class << self; attr_writer :record_type, :key_name; end
end
base.extend ClassMethods
ActionView::Base.send :include, FragmentsHelper
end
|
Instance Method Details
#cache_exist? ⇒ Boolean
533
534
535
536
|
# File 'lib/fragmentary/fragment.rb', line 533
def cache_exist?
cache_store.exist?(ActiveSupport::Cache.expand_cache_key(self, 'views'))
end
|
#cache_store ⇒ Object
492
493
494
|
# File 'lib/fragmentary/fragment.rb', line 492
def cache_store
self.class.cache_store
end
|
#child(options) ⇒ Object
Note that this method can be called in two different contexts. One is as part of rendering the parent fragment, which means that the parent was obtained using either Fragment.root or a previous invocation of this method. In this case, the children will have already been loaded and indexed. The second is when the child is being rendered on its own, e.g. inserted by ajax into a parent that is already on the page. In this case the children won’t have already been loaded or indexed.
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
|
# File 'lib/fragmentary/fragment.rb', line 442
def child(options)
if child = options[:child]
raise ArgumentError, "You passed a child fragment to a parent it's not a child of." unless child.parent_id == self.id
child
else
existing = options.delete(:existing)
derived_options = {:root_id => root_id || id}
derived_options.merge!(:record_id => record_id) unless options[:type].constantize.needs_record_id?
klass, search_attributes, options = Fragment.base_class.attributes(options.reverse_merge(derived_options))
select_attributes = search_attributes.merge(:type => klass.name)
if child_search_key and keyed_children = indexed_children.try(:[], select_attributes[child_search_key])
select_attributes.delete(child_search_key)
end
fragment = (keyed_children || children).to_a.find{|child| select_attributes.all?{|key, value| child.send(key) == value}}
unless fragment or existing
fragment = klass.new(search_attributes.merge(options))
children << fragment end
if fragment
fragment_children = fragment.children
fragment.set_indexed_children if fragment.child_search_key
end
fragment
end
end
|
#child_search_key ⇒ Object
423
424
425
|
# File 'lib/fragmentary/fragment.rb', line 423
def child_search_key
self.class.child_search_key
end
|
#delete_cache ⇒ Object
510
511
512
|
# File 'lib/fragmentary/fragment.rb', line 510
def delete_cache
cache_store.delete(ActiveSupport::Cache.expand_cache_key(self, 'views'))
end
|
#delete_matched_cache ⇒ Object
506
507
508
|
# File 'lib/fragmentary/fragment.rb', line 506
def delete_matched_cache
cache_store.delete_matched(Regexp.new("#{self.class.model_name.cache_key}/#{id}"))
end
|
#destroy(options = {}) ⇒ Object
501
502
503
504
|
# File 'lib/fragmentary/fragment.rb', line 501
def destroy(options = {})
options.delete(:delete_matches) ? delete_matched_cache : delete_cache
super()
end
|
#existing_child(options) ⇒ Object
433
434
435
|
# File 'lib/fragmentary/fragment.rb', line 433
def existing_child(options)
child(options.merge(:existing => true))
end
|
#record_type ⇒ Object
If this fragment’s class needs a record_id, it will also have a record_type. If not, we copy the record_id from the parent, if it has one.
482
483
484
|
# File 'lib/fragmentary/fragment.rb', line 482
def record_type
@record_type ||= self.class.needs_record_id? ? self.class.record_type : self.parent.record_type
end
|
#request ⇒ Object
Returns a Request object that can be used to send a server request for the fragment content
567
568
569
|
# File 'lib/fragmentary/fragment.rb', line 567
def request
requestable? ? @request ||= Request.new(request_method, request_path, request_parameters, request_options) : nil
end
|
#request_method ⇒ Object
Request-related methods… Note: subclasses that define request_path need to also define self.request_path and should define the instance method in terms of the class method. Likewise, those that define request_parameters also need to defined self.request_parameters and define the instance method in terms of the class method. Subclasses generally don’t need to define request_method or request_options, but may need to define self.request_options. The instance method version request_options is defined in terms of the class method below.
Also… subclasses that define request_path also need to define self.request, but not the instance method request since that is defined below in terms of its constituent request arguments. The reason is that the class method self.request generally takes a parameter (e.g. a record_id or a key), and this is used in different ways depending on the class, whereas the instance method takes the same form regardless of the class.
550
551
552
|
# File 'lib/fragmentary/fragment.rb', line 550
def request_method
self.class.request_method
end
|
#request_options ⇒ Object
558
559
560
|
# File 'lib/fragmentary/fragment.rb', line 558
def request_options
self.class.request_options
end
|
#request_parameters ⇒ Object
554
555
556
|
# File 'lib/fragmentary/fragment.rb', line 554
def request_parameters
self.class.request_parameters end
|
#request_queues ⇒ Object
Though each fragment is typically associated with a particular user_type, touching a root fragment will send page requests for the path associated with the fragment to queues for all relevant user_types for this fragment class.
488
489
490
|
# File 'lib/fragmentary/fragment.rb', line 488
def request_queues
self.class.request_queues
end
|
#requestable? ⇒ Boolean
562
563
564
|
# File 'lib/fragmentary/fragment.rb', line 562
def requestable?
@requestable ||= respond_to? :request_path
end
|
#set_indexed_children ⇒ Object
427
428
429
430
431
|
# File 'lib/fragmentary/fragment.rb', line 427
def set_indexed_children
return unless child_search_key
obj = Hash.new {|h, indx| h[indx] = []}
@indexed_children = children.each_with_object(obj) {|child, collection| collection[child.send(child_search_key)] << child }
end
|
#touch(*args, no_request: false) ⇒ Object
496
497
498
499
|
# File 'lib/fragmentary/fragment.rb', line 496
def touch(*args, no_request: false)
request_queues.each{|key, hsh| hsh.each{|key2, queue| queue << request}} if request && !no_request
super(*args)
end
|
#touch_or_destroy ⇒ Object
Touch this fragment and all descendants that have entries in the cache. Destroy any that don’t have cache entries.
522
523
524
525
526
527
528
529
530
531
|
# File 'lib/fragmentary/fragment.rb', line 522
def touch_or_destroy
puts " touch_or_destroy #{self.class.name} #{id}"
if cache_exist?
children.each(&:touch_or_destroy)
touch(:no_request => true) unless children.any?
else
destroy end
end
|
#touch_tree(no_request: false) ⇒ Object
514
515
516
517
518
|
# File 'lib/fragmentary/fragment.rb', line 514
def touch_tree(no_request: false)
children.each{|child| child.touch_tree(:no_request => no_request)}
touch(:no_request => no_request) unless children.any?
end
|