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/ext/object.rb,
lib/bullet/ext/string.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/active_record72.rb,
lib/bullet/active_record80.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, Ext, 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 =
'8.0.0'

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_record72?, active_record7?, active_record80?, active_record8?, 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)


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

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



171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/bullet.rb', line 171

def end_request
  Thread.current.thread_variable_set(:bullet_start, nil)
  Thread.current.thread_variable_set(:bullet_notification_collector, nil)

  Thread.current.thread_variable_set(:bullet_object_associations, nil)
  Thread.current.thread_variable_set(:bullet_call_object_associations, nil)
  Thread.current.thread_variable_set(:bullet_possible_objects, nil)
  Thread.current.thread_variable_set(:bullet_impossible_objects, nil)
  Thread.current.thread_variable_set(:bullet_inversed_objects, nil)
  Thread.current.thread_variable_set(:bullet_eager_loadings, nil)

  Thread.current.thread_variable_set(:bullet_counter_possible_objects, nil)
  Thread.current.thread_variable_set(:bullet_counter_impossible_objects, nil)
end


215
216
217
218
219
# File 'lib/bullet.rb', line 215

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

.gather_inline_notificationsObject



201
202
203
204
205
# File 'lib/bullet.rb', line 201

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)


261
262
263
264
265
# File 'lib/bullet.rb', line 261

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)


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

def notification?
  return unless start?

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

.notification_collectorObject



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

def notification_collector
  Thread.current.thread_variable_get(:bullet_notification_collector)
end

.perform_out_of_channel_notifications(env = {}) ⇒ Object



207
208
209
210
211
212
213
# File 'lib/bullet.rb', line 207

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



237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
# File 'lib/bullet.rb', line 237

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)


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

def start?
  enable? && Thread.current.thread_variable_get(:bullet_start)
end

.start_requestObject



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

def start_request
  Thread.current.thread_variable_set(:bullet_start, true)
  Thread.current.thread_variable_set(:bullet_notification_collector, Bullet::NotificationCollector.new)

  Thread.current.thread_variable_set(:bullet_object_associations, Bullet::Registry::Base.new)
  Thread.current.thread_variable_set(:bullet_call_object_associations, Bullet::Registry::Base.new)
  Thread.current.thread_variable_set(:bullet_possible_objects, Bullet::Registry::Object.new)
  Thread.current.thread_variable_set(:bullet_impossible_objects, Bullet::Registry::Object.new)
  Thread.current.thread_variable_set(:bullet_inversed_objects, Bullet::Registry::Base.new)
  Thread.current.thread_variable_set(:bullet_eager_loadings, Bullet::Registry::Association.new)
  Thread.current.thread_variable_set(:bullet_call_stacks, Bullet::Registry::CallStack.new)

  unless Thread.current.thread_variable_get(:bullet_counter_possible_objects)
    Thread.current.thread_variable_set(:bullet_counter_possible_objects, Bullet::Registry::Object.new)
  end

  unless Thread.current.thread_variable_get(:bullet_counter_impossible_objects)
    Thread.current.thread_variable_set(:bullet_counter_impossible_objects, Bullet::Registry::Object.new)
  end
end

.text_notificationsObject



221
222
223
224
225
226
227
# File 'lib/bullet.rb', line 221

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



229
230
231
232
233
234
235
# File 'lib/bullet.rb', line 229

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