display_case 0.0.8 → 0.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md CHANGED
@@ -78,6 +78,7 @@ Several configuration options can be set via an initializer:
78
78
  1. `exhibits` If `explicit` is true you must explicitly set the Exhibits you wish to use in the order you want them evaluated. You can set `config.exhibits = [AnExhibit,AnotherExhibit]` in your initializers/display_case.rb.
79
79
  1. `cache_store` If you configure a cache store, you can use it by calling the `cache` method in your Exhibits (see below).
80
80
  1. `logging_enabled` Setting this to `true` will provide debug information about exhibits to the Rails logger, but may adversely affect performance when many objects are being exhibited.
81
+ 1. `smart_matching` A boolean indicating whether Exhibits with names that are similar to context should be favored over other exhibits. By default, this is true.
81
82
 
82
83
  An example `initializers/display_case.rb`
83
84
  ```
@@ -9,10 +9,6 @@ module DisplayCase
9
9
  partialize_name(__getobj__.class.name)
10
10
  end
11
11
  end
12
-
13
- def render(template)
14
- template.render(:partial => to_partial_path, :object => self)
15
- end
16
12
  end
17
13
  end
18
14
 
@@ -27,18 +27,27 @@ module DisplayCase
27
27
  # A boolean indicating whether or not to log to the Rails logger
28
28
  attr_accessor :logging_enabled
29
29
 
30
+ # A boolean indicating whether Exhibits with names that are similar to
31
+ # context should be favored over other exhibits. By default, this is true
32
+ attr_accessor :smart_matching
33
+
30
34
  def initialize
31
35
  @definition_file_paths = %w(app/exhibits)
32
36
  @explicit = false
33
37
  @exhibits = []
34
38
  @cache_store = nil
35
39
  @logging_enabled = false
40
+ @smart_matching = true
36
41
  end
37
42
 
38
43
  def explicit?
39
44
  explicit
40
45
  end
41
46
 
47
+ def smart_matching?
48
+ smart_matching
49
+ end
50
+
42
51
  def logging_enabled?
43
52
  defined? ::Rails and logging_enabled
44
53
  end
@@ -7,7 +7,7 @@ module DisplayCase
7
7
  def self.applicable_to?(object, context=nil)
8
8
  # ActiveRecord::Relation, surprisingly, is not Enumerable. But it
9
9
  # behaves sufficiently similarly for our purposes.
10
- object_is_any_of?(object, 'Enumerable', 'ActiveRecord::Relation')
10
+ object.respond_to?(:each)
11
11
  end
12
12
 
13
13
  # Wrap an Enumerable method which returns another collection
@@ -45,7 +45,7 @@ module DisplayCase
45
45
  def to_ary
46
46
  self
47
47
  end
48
-
48
+
49
49
  # See https://github.com/objects-on-rails/display-case/issues/27
50
50
  def to_json
51
51
  as_json.to_json
@@ -30,10 +30,9 @@ module DisplayCase
30
30
  end
31
31
 
32
32
  object = BasicExhibit.new(Exhibited.new(object, context), context)
33
- similar, unsimilar = partition_by_name(exhibits, context)
34
33
 
35
34
  # done w/ unsimilar first since the last applied exhibit is the top-most one
36
- (unsimilar + similar).inject(object) do |object, exhibit_class|
35
+ sorted_exhibits(context).inject(object) do |object, exhibit_class|
37
36
  exhibit_class.exhibit_if_applicable(object, context)
38
37
  end.tap do |obj|
39
38
  ::Rails.logger.debug "Exhibits applied: #{obj.inspect_exhibits}" if DisplayCase.configuration.logging_enabled?
@@ -41,8 +40,6 @@ module DisplayCase
41
40
  end
42
41
 
43
42
  def self.partition_by_name(exhibits, context=nil)
44
- return [], exhibits if DisplayCase.configuration.explicit? || context.nil? || context.class.name.nil?
45
-
46
43
  exhibits.partition do |exhibit_class|
47
44
  exhibit_name = exhibit_class.name.to_s.downcase.gsub("exhibit", "")
48
45
  exhibit_name.length > 0 && context.class.name.downcase.include?(exhibit_name)
@@ -50,6 +47,21 @@ module DisplayCase
50
47
  end
51
48
  private_class_method :partition_by_name
52
49
 
50
+ def self.sorted_exhibits(context)
51
+ if smart_matching?(context)
52
+ similar, unsimilar = partition_by_name(exhibits, context)
53
+ unsimilar + similar
54
+ else
55
+ exhibits
56
+ end
57
+ end
58
+ private_class_method :sorted_exhibits
59
+
60
+ def self.smart_matching?(context)
61
+ DisplayCase.configuration.smart_matching? && !(DisplayCase.configuration.explicit? || context.nil? || context.class.name.nil?)
62
+ end
63
+ private_class_method :smart_matching?
64
+
53
65
  def self.exhibit_if_applicable(object, context)
54
66
  if applicable_to?(object, context)
55
67
  new(object, context)
@@ -107,15 +119,15 @@ module DisplayCase
107
119
  def class
108
120
  __getobj__.class
109
121
  end
110
-
122
+
111
123
  alias_method :__kind_of__?, :kind_of?
112
124
  def kind_of?(klass)
113
125
  __getobj__.kind_of?(klass)
114
126
  end
115
-
127
+
116
128
  alias_method :__is_a__?, :is_a?
117
129
  alias_method :is_a?, :kind_of?
118
-
130
+
119
131
  alias_method :__instance_of__?, :instance_of?
120
132
  def instance_of?(klass)
121
133
  __getobj__.instance_of?(klass)
@@ -138,10 +150,14 @@ module DisplayCase
138
150
  "#{inspect_exhibits}(#{__getobj__.inspect})"
139
151
  end
140
152
 
153
+ def render(template)
154
+ template.render(:partial => to_partial_path, :object => self)
155
+ end
156
+
141
157
  def exhibited?
142
158
  true
143
159
  end
144
-
160
+
145
161
  def cache(key, options = {}, &block)
146
162
  if DisplayCase.configuration.cache_store
147
163
  DisplayCase.configuration.cache_store.fetch(key, options, &block)
@@ -7,7 +7,26 @@ module DisplayCase
7
7
  class NameClassComparator
8
8
  def call(object, *classes)
9
9
  # Note that '&' is the set intersection operator for Arrays.
10
- (classes.map(&:to_s) & object.class.ancestors.map(&:name)).any?
10
+ (classes.map(&:to_s) & object.class.ancestors.map {|c| name_for(c)}).any?
11
+ end
12
+
13
+ private
14
+ class ClassNameTracker
15
+ def initialize
16
+ @data = Hash.new {|h, k| h[k] = k.name}
17
+ end
18
+
19
+ def name_for(kls)
20
+ @data[kls]
21
+ end
22
+ end
23
+
24
+ def class_name_tracker
25
+ @class_name_tracker ||= ClassNameTracker.new
26
+ end
27
+
28
+ def name_for(cls)
29
+ class_name_tracker.name_for(cls)
11
30
  end
12
31
  end
13
32
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: display_case
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8
4
+ version: 0.0.9
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-07-13 00:00:00.000000000Z
12
+ date: 2013-07-22 00:00:00.000000000Z
13
13
  dependencies: []
14
14
  description: An implementation of the Exhibit pattern, as described in Objects on
15
15
  Rails