display_case 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
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