Module: Bullet

Extended by:
Dependency
Defined in:
lib/bullet.rb,
lib/bullet/rack.rb,
lib/bullet/version.rb,
lib/bullet/detector.rb,
lib/bullet/registry.rb,
lib/bullet/mongoid4x.rb,
lib/bullet/mongoid5x.rb,
lib/bullet/mongoid6x.rb,
lib/bullet/mongoid7x.rb,
lib/bullet/mongoid8x.rb,
lib/bullet/active_job.rb,
lib/bullet/dependency.rb,
lib/bullet/notification.rb,
lib/bullet/detector/base.rb,
lib/bullet/registry/base.rb,
lib/bullet/active_record4.rb,
lib/bullet/active_record5.rb,
lib/bullet/active_record41.rb,
lib/bullet/active_record42.rb,
lib/bullet/active_record52.rb,
lib/bullet/active_record60.rb,
lib/bullet/active_record61.rb,
lib/bullet/active_record70.rb,
lib/bullet/active_record71.rb,
lib/bullet/registry/object.rb,
lib/bullet/notification/base.rb,
lib/bullet/stack_trace_filter.rb,
lib/bullet/registry/call_stack.rb,
lib/bullet/detector/association.rb,
lib/bullet/registry/association.rb,
lib/bullet/detector/counter_cache.rb,
lib/bullet/notification_collector.rb,
lib/bullet/detector/n_plus_one_query.rb,
lib/bullet/notification/counter_cache.rb,
lib/generators/bullet/install_generator.rb,
lib/bullet/detector/unused_eager_loading.rb,
lib/bullet/notification/n_plus_one_query.rb,
lib/bullet/notification/unused_eager_loading.rb

Defined Under Namespace

Modules: ActiveJob, ActiveRecord, Dependency, Detector, Generators, Mongoid, Notification, Registry, SaveWithBulletSupport, StackTraceFilter Classes: BulletRailtie, NotificationCollector, Rack

Constant Summary collapse

DETECTORS =
[
  Bullet::Detector::NPlusOneQuery,
  Bullet::Detector::UnusedEagerLoading,
  Bullet::Detector::CounterCache
].freeze
VERSION =
'7.1.6'

Class Attribute Summary collapse

Class Method Summary collapse

Methods included from Dependency

active_record40?, active_record41?, active_record42?, active_record4?, active_record50?, active_record51?, active_record52?, active_record5?, active_record60?, active_record61?, active_record6?, active_record70?, active_record71?, active_record7?, active_record?, active_record_version, mongoid4x?, mongoid5x?, mongoid6x?, mongoid7x?, mongoid8x?, mongoid?, mongoid_version

Class Attribute Details

Returns the value of attribute add_footer.



43
44
45
# File 'lib/bullet.rb', line 43

def add_footer
  @add_footer
end

.always_append_html_bodyObject

Returns the value of attribute always_append_html_body.



43
44
45
# File 'lib/bullet.rb', line 43

def always_append_html_body
  @always_append_html_body
end

.counter_cache_enable=(value) ⇒ Object (writeonly)

Sets the attribute counter_cache_enable

Parameters:

  • value

    the value to set the attribute counter_cache_enable to.



36
37
38
# File 'lib/bullet.rb', line 36

def counter_cache_enable=(value)
  @counter_cache_enable = value
end

.n_plus_one_query_enable=(value) ⇒ Object (writeonly)

Sets the attribute n_plus_one_query_enable

Parameters:

  • value

    the value to set the attribute n_plus_one_query_enable to.



36
37
38
# File 'lib/bullet.rb', line 36

def n_plus_one_query_enable=(value)
  @n_plus_one_query_enable = value
end

.orm_patches_appliedObject

Returns the value of attribute orm_patches_applied.



43
44
45
# File 'lib/bullet.rb', line 43

def orm_patches_applied
  @orm_patches_applied
end

.safelistObject (readonly)

Returns the value of attribute safelist.



42
43
44
# File 'lib/bullet.rb', line 42

def safelist
  @safelist
end

.skip_html_injection=(value) ⇒ Object (writeonly)

Sets the attribute skip_html_injection

Parameters:

  • value

    the value to set the attribute skip_html_injection to.



36
37
38
# File 'lib/bullet.rb', line 36

def skip_html_injection=(value)
  @skip_html_injection = value
end

.skip_http_headersObject

Returns the value of attribute skip_http_headers.



43
44
45
# File 'lib/bullet.rb', line 43

def skip_http_headers
  @skip_http_headers
end

.skip_user_in_notificationObject

Returns the value of attribute skip_user_in_notification.



43
44
45
# File 'lib/bullet.rb', line 43

def skip_user_in_notification
  @skip_user_in_notification
end

.stacktrace_excludesObject



107
108
109
# File 'lib/bullet.rb', line 107

def stacktrace_excludes
  @stacktrace_excludes ||= []
end

.stacktrace_includesObject



103
104
105
# File 'lib/bullet.rb', line 103

def stacktrace_includes
  @stacktrace_includes ||= []
end

.unused_eager_loading_enable=(value) ⇒ Object (writeonly)

Sets the attribute unused_eager_loading_enable

Parameters:

  • value

    the value to set the attribute unused_eager_loading_enable to.



36
37
38
# File 'lib/bullet.rb', line 36

def unused_eager_loading_enable=(value)
  @unused_eager_loading_enable = value
end

Class Method Details

.add_safelist(options) ⇒ Object



111
112
113
114
115
# File 'lib/bullet.rb', line 111

def add_safelist(options)
  reset_safelist
  @safelist[options[:type]][options[:class_name]] ||= []
  @safelist[options[:type]][options[:class_name]] << options[:association].to_sym
end

.app_rootObject

Rails.root might be nil if ‘railties` is a dependency on a project that does not use Rails



87
88
89
# File 'lib/bullet.rb', line 87

def app_root
  @app_root ||= (defined?(::Rails.root) && !::Rails.root.nil? ? Rails.root.to_s : Dir.pwd).to_s
end

.bullet_logger=(active) ⇒ Object



136
137
138
139
140
141
142
143
144
# File 'lib/bullet.rb', line 136

def bullet_logger=(active)
  if active
    require 'fileutils'
    FileUtils.mkdir_p(app_root + '/log')
    bullet_log_file = File.open("#{app_root}/log/bullet.log", 'a+')
    bullet_log_file.sync = true
    UniformNotifier.customized_logger = bullet_log_file
  end
end

.clear_safelistObject



132
133
134
# File 'lib/bullet.rb', line 132

def clear_safelist
  @safelist = nil
end

.console_enabled?Boolean

Returns:

  • (Boolean)


252
253
254
# File 'lib/bullet.rb', line 252

def console_enabled?
  UniformNotifier.active_notifiers.include?(UniformNotifier::JavascriptConsole)
end

.counter_cache_enable?Boolean

Returns:

  • (Boolean)


99
100
101
# File 'lib/bullet.rb', line 99

def counter_cache_enable?
  enable? && !!@counter_cache_enable
end

.debug(title, message) ⇒ Object



146
147
148
# File 'lib/bullet.rb', line 146

def debug(title, message)
  puts "[Bullet][#{title}] #{message}" if ENV['BULLET_DEBUG'] == 'true'
end

.delete_safelist(options) ⇒ Object



117
118
119
120
121
122
# File 'lib/bullet.rb', line 117

def delete_safelist(options)
  reset_safelist
  @safelist[options[:type]][options[:class_name]] ||= []
  @safelist[options[:type]][options[:class_name]].delete(options[:association].to_sym)
  @safelist[options[:type]].delete_if { |_key, val| val.empty? }
end

.enable=(enable) ⇒ Object Also known as: enabled=



65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/bullet.rb', line 65

def enable=(enable)
  @enable = @n_plus_one_query_enable = @unused_eager_loading_enable = @counter_cache_enable = enable

  if enable?
    reset_safelist
    unless orm_patches_applied
      self.orm_patches_applied = true
      Bullet::Mongoid.enable if mongoid?
      Bullet::ActiveRecord.enable if active_record?
    end
  end
end

.enable?Boolean Also known as: enabled?

Returns:

  • (Boolean)


80
81
82
# File 'lib/bullet.rb', line 80

def enable?
  !!@enable
end

.end_requestObject



166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/bullet.rb', line 166

def end_request
  Thread.current[:bullet_start] = nil
  Thread.current[:bullet_notification_collector] = nil

  Thread.current[:bullet_object_associations] = nil
  Thread.current[:bullet_call_object_associations] = nil
  Thread.current[:bullet_possible_objects] = nil
  Thread.current[:bullet_impossible_objects] = nil
  Thread.current[:bullet_inversed_objects] = nil
  Thread.current[:bullet_eager_loadings] = nil

  Thread.current[:bullet_counter_possible_objects] = nil
  Thread.current[:bullet_counter_impossible_objects] = nil
end


210
211
212
213
214
# File 'lib/bullet.rb', line 210

def footer_info
  info = []
  notification_collector.collection.each { |notification| info << notification.short_notice }
  info
end

.gather_inline_notificationsObject



196
197
198
199
200
# File 'lib/bullet.rb', line 196

def gather_inline_notifications
  responses = []
  for_each_active_notifier_with_notification { |notification| responses << notification.notify_inline }
  responses.join("\n")
end

.get_safelist_associations(type, class_name) ⇒ Object



124
125
126
# File 'lib/bullet.rb', line 124

def get_safelist_associations(type, class_name)
  Array.wrap(@safelist[type][class_name])
end

.inject_into_page?Boolean

Returns:

  • (Boolean)


256
257
258
259
260
# File 'lib/bullet.rb', line 256

def inject_into_page?
  return false if defined?(@skip_html_injection) && @skip_html_injection

  console_enabled? || add_footer
end

.n_plus_one_query_enable?Boolean

Returns:

  • (Boolean)


91
92
93
# File 'lib/bullet.rb', line 91

def n_plus_one_query_enable?
  enable? && !!@n_plus_one_query_enable
end

.notification?Boolean

Returns:

  • (Boolean)


189
190
191
192
193
194
# File 'lib/bullet.rb', line 189

def notification?
  return unless start?

  Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
  notification_collector.notifications_present?
end

.notification_collectorObject



185
186
187
# File 'lib/bullet.rb', line 185

def notification_collector
  Thread.current[:bullet_notification_collector]
end

.perform_out_of_channel_notifications(env = {}) ⇒ Object



202
203
204
205
206
207
208
# File 'lib/bullet.rb', line 202

def perform_out_of_channel_notifications(env = {})
  request_uri = build_request_uri(env)
  for_each_active_notifier_with_notification do |notification|
    notification.url = request_uri
    notification.notify_out_of_channel
  end
end

.profileObject



232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
# File 'lib/bullet.rb', line 232

def profile
  return_value = nil

  if Bullet.enable?
    begin
      Bullet.start_request

      return_value = yield

      Bullet.perform_out_of_channel_notifications if Bullet.notification?
    ensure
      Bullet.end_request
    end
  else
    return_value = yield
  end

  return_value
end

.raise=(should_raise) ⇒ Object



55
56
57
# File 'lib/bullet.rb', line 55

def raise=(should_raise)
  UniformNotifier.raise = (should_raise ? Notification::UnoptimizedQueryError : false)
end

.reset_safelistObject



128
129
130
# File 'lib/bullet.rb', line 128

def reset_safelist
  @safelist ||= { n_plus_one_query: {}, unused_eager_loading: {}, counter_cache: {} }
end

.start?Boolean

Returns:

  • (Boolean)


181
182
183
# File 'lib/bullet.rb', line 181

def start?
  enable? && Thread.current[:bullet_start]
end

.start_requestObject



150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/bullet.rb', line 150

def start_request
  Thread.current[:bullet_start] = true
  Thread.current[:bullet_notification_collector] = Bullet::NotificationCollector.new

  Thread.current[:bullet_object_associations] = Bullet::Registry::Base.new
  Thread.current[:bullet_call_object_associations] = Bullet::Registry::Base.new
  Thread.current[:bullet_possible_objects] = Bullet::Registry::Object.new
  Thread.current[:bullet_impossible_objects] = Bullet::Registry::Object.new
  Thread.current[:bullet_inversed_objects] = Bullet::Registry::Base.new
  Thread.current[:bullet_eager_loadings] = Bullet::Registry::Association.new
  Thread.current[:bullet_call_stacks] = Bullet::Registry::CallStack.new

  Thread.current[:bullet_counter_possible_objects] ||= Bullet::Registry::Object.new
  Thread.current[:bullet_counter_impossible_objects] ||= Bullet::Registry::Object.new
end

.text_notificationsObject



216
217
218
219
220
221
222
# File 'lib/bullet.rb', line 216

def text_notifications
  info = []
  notification_collector.collection.each do |notification|
    info << notification.notification_data.values.compact.join("\n")
  end
  info
end

.unused_eager_loading_enable?Boolean

Returns:

  • (Boolean)


95
96
97
# File 'lib/bullet.rb', line 95

def unused_eager_loading_enable?
  enable? && !!@unused_eager_loading_enable
end

.warningsObject



224
225
226
227
228
229
230
# File 'lib/bullet.rb', line 224

def warnings
  notification_collector.collection.each_with_object({}) do |notification, warnings|
    warning_type = notification.class.to_s.split(':').last.tableize
    warnings[warning_type] ||= []
    warnings[warning_type] << notification
  end
end