better_record 0.1.1 → 0.2.0

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.
Files changed (98) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +12 -18
  3. data/app/models/better_record/table_size.rb +30 -28
  4. data/config/initializers/{money_type.rb → active_record/money_type.rb} +0 -0
  5. data/config/initializers/{boolean.rb → core_ext/boolean.rb} +0 -0
  6. data/config/initializers/core_ext/date.rb +9 -0
  7. data/config/initializers/{integer.rb → core_ext/integer.rb} +0 -0
  8. data/config/initializers/dkim.rb +7 -0
  9. data/config/initializers/redis_store.rb +24 -0
  10. data/lib/better_record.rb +6 -4
  11. data/lib/better_record/engine.rb +7 -0
  12. data/lib/better_record/fake_redis.rb +94 -0
  13. data/lib/better_record/version.rb +1 -1
  14. data/lib/tasks/spec/attributes.rake +7 -1
  15. data/spec/dummy/Rakefile +6 -0
  16. data/spec/dummy/app/assets/config/manifest.js +4 -0
  17. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  18. data/spec/dummy/app/assets/javascripts/cable.js +13 -0
  19. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  20. data/spec/dummy/app/channels/application_cable/channel.rb +4 -0
  21. data/spec/dummy/app/channels/application_cable/connection.rb +4 -0
  22. data/spec/dummy/app/controllers/application_controller.rb +2 -0
  23. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  24. data/spec/dummy/app/jobs/application_job.rb +2 -0
  25. data/spec/dummy/app/mailers/application_mailer.rb +4 -0
  26. data/spec/dummy/app/models/application_record.rb +3 -0
  27. data/spec/dummy/app/models/test_audit.rb +2 -0
  28. data/spec/dummy/app/models/test_custom_audit.rb +2 -0
  29. data/spec/dummy/app/views/layouts/application.html.erb +15 -0
  30. data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
  31. data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
  32. data/spec/dummy/bin/bundle +3 -0
  33. data/spec/dummy/bin/rails +4 -0
  34. data/spec/dummy/bin/rake +4 -0
  35. data/spec/dummy/bin/setup +36 -0
  36. data/spec/dummy/bin/update +31 -0
  37. data/spec/dummy/bin/yarn +11 -0
  38. data/spec/dummy/config.ru +5 -0
  39. data/spec/dummy/config/application.rb +19 -0
  40. data/spec/dummy/config/boot.rb +5 -0
  41. data/spec/dummy/config/cable.yml +10 -0
  42. data/spec/dummy/config/database.yml +25 -0
  43. data/spec/dummy/config/environment.rb +5 -0
  44. data/spec/dummy/config/environments/development.rb +61 -0
  45. data/spec/dummy/config/environments/production.rb +94 -0
  46. data/spec/dummy/config/environments/test.rb +46 -0
  47. data/spec/dummy/config/initializers/application_controller_renderer.rb +8 -0
  48. data/spec/dummy/config/initializers/assets.rb +14 -0
  49. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  50. data/spec/dummy/config/initializers/better_record.rb +42 -0
  51. data/{config → spec/dummy/config}/initializers/content_security_policy.rb +0 -0
  52. data/spec/dummy/config/initializers/cookies_serializer.rb +5 -0
  53. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  54. data/spec/dummy/config/initializers/inflections.rb +16 -0
  55. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  56. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  57. data/spec/dummy/config/locales/en.yml +33 -0
  58. data/spec/dummy/config/puma.rb +34 -0
  59. data/spec/dummy/config/routes.rb +3 -0
  60. data/spec/dummy/config/spring.rb +6 -0
  61. data/spec/dummy/config/storage.yml +34 -0
  62. data/spec/dummy/db/migrate/20180725233004_create_test_audits.rb +11 -0
  63. data/spec/dummy/db/migrate/20180725233007_create_test_custom_audits.rb +12 -0
  64. data/spec/dummy/db/migrate/20180725235254_create_better_record_db_functions.better_record.rb +95 -0
  65. data/spec/dummy/db/migrate/20180725235255_create_better_record_table_sizes.better_record.rb +25 -0
  66. data/spec/dummy/db/structure.sql +781 -0
  67. data/spec/dummy/lib/templates/active_record/model/model.rb +31 -0
  68. data/spec/dummy/lib/templates/rspec/model/model_spec.rb +17 -0
  69. data/spec/dummy/log/development.log +2495 -0
  70. data/spec/dummy/log/test.log +197 -0
  71. data/spec/dummy/package.json +5 -0
  72. data/spec/dummy/public/404.html +67 -0
  73. data/spec/dummy/public/422.html +67 -0
  74. data/spec/dummy/public/500.html +66 -0
  75. data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
  76. data/spec/dummy/public/apple-touch-icon.png +0 -0
  77. data/spec/dummy/public/favicon.ico +0 -0
  78. data/spec/dummy/spec/factories/test_audits.rb +7 -0
  79. data/spec/dummy/spec/factories/test_custom_audits.rb +8 -0
  80. data/spec/dummy/spec/models/test_audit_spec.rb +5 -0
  81. data/spec/dummy/spec/models/test_custom_audit_spec.rb +5 -0
  82. data/spec/factories/better_record_table_sizes.rb +16 -0
  83. data/spec/factories/test_audits.rb +7 -0
  84. data/spec/factories/test_custom_audits.rb +8 -0
  85. data/spec/lib/generators/better_record/install_generator_test.rb +16 -0
  86. data/spec/method_helper.rb +7 -0
  87. data/spec/method_helper/functions.rb +9 -0
  88. data/spec/method_helper/functions/boolean_column.rb +52 -0
  89. data/spec/method_helper/functions/has_valid_factory.rb +20 -0
  90. data/spec/method_helper/functions/optional_column.rb +17 -0
  91. data/spec/method_helper/functions/required_column.rb +35 -0
  92. data/spec/models/better_record/logged_action_spec.rb +35 -0
  93. data/spec/models/better_record/table_size_spec.rb +26 -0
  94. data/spec/models/test_audit_spec.rb +5 -0
  95. data/spec/models/test_custom_audit_spec.rb +5 -0
  96. data/spec/rails_helper.rb +36 -0
  97. data/spec/tmp/testes +0 -0
  98. metadata +204 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 714bdfe5593dca0ec99aa991dc68e1c432f2ff730ad8c78bad43d6172714b10c
4
- data.tar.gz: 05523c1546ac5d85673b2f8d9473dc2371f9d6bce315d4fb6aa77832b3cdedd9
3
+ metadata.gz: 13ce1aa3a062c924a936fea3c3fcb1f4e10fba5e775e0af7ff0a23aad74e9cd0
4
+ data.tar.gz: b89dc1cbe073de860b99c0389eada900eeab147b775d4fe6887f2a1860b8f248
5
5
  SHA512:
6
- metadata.gz: 0b4fc40ce72b44600fe6a8167745f1a3147080ea38afecb84fe2bb35b599dc7b6ec22ba6f0b71963a020c08805fd5697437dadcfaaa592612f1032bf3195e88d
7
- data.tar.gz: 1d40b47387cae6dbf65d539ae10aea6b29074b3837fc218604c407390f348df9b4cd7b8bf82981fa8a31a5f0f4603b7c685b3574547eb1058dd39f8bc8d7166a
6
+ metadata.gz: 566ba8d84f32b08046359cbccac6edccc2d8e1e1a47598c94a16fbc6c9a4808bc28c56128f546d08f48fc70bd5e6148590ba41224bc7c39336e5a8cc79289dbb
7
+ data.tar.gz: 65f4d70fb45fd202dc99e094a1ff4609884d6fcfb3983cdbbd38e990343888ac0ac668d26390b69313499f9507203aa492c8a904421450b0620c30702c102629
data/Rakefile CHANGED
@@ -1,27 +1,21 @@
1
+ #!/usr/bin/env rake
1
2
  begin
2
- require 'bundler/setup'
3
+ require 'bundler/setup'
3
4
  rescue LoadError
4
- puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
6
  end
6
7
 
7
- require 'rdoc/task'
8
+ APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
9
+ load 'rails/tasks/engine.rake'
8
10
 
9
- RDoc::Task.new(:rdoc) do |rdoc|
10
- rdoc.rdoc_dir = 'rdoc'
11
- rdoc.title = 'BetterRecord'
12
- rdoc.options << '--line-numbers'
13
- rdoc.rdoc_files.include('README.md')
14
- rdoc.rdoc_files.include('lib/**/*.rb')
15
- end
11
+ Bundler::GemHelper.install_tasks
16
12
 
17
- require 'bundler/gem_tasks'
13
+ Dir[File.join(File.dirname(__FILE__), 'lib/tasks/**/*.rake')].each {|f| load f }
18
14
 
19
- require 'rake/testtask'
15
+ require 'rspec/core'
16
+ require 'rspec/core/rake_task'
20
17
 
21
- Rake::TestTask.new(:test) do |t|
22
- t.libs << 'test'
23
- t.pattern = 'test/**/*_test.rb'
24
- t.verbose = false
25
- end
18
+ desc "Run all specs in spec directory (excluding plugin specs)"
19
+ RSpec::Core::RakeTask.new(spec: 'app:db:test:prepare')
26
20
 
27
- task default: :test
21
+ task default: :spec
@@ -1,38 +1,38 @@
1
1
  module BetterRecord
2
2
  class TableSize < Base
3
3
  # == Constants ============================================================
4
- LOAD_TABLE_DATA_SQL = <<-SQL
4
+ UPDATE_TABLE_SIZES_SQL = <<-SQL
5
5
  BEGIN WORK;
6
- LOCK #{BetterRecord.db_audit_schema}.table_sizes;
7
- TRUNCATE #{BetterRecord.db_audit_schema}.table_sizes;
8
- INSERT INTO #{BetterRecord.db_audit_schema}.table_sizes
9
- (
10
- SELECT
11
- *,
12
- pg_size_pretty(total_bytes) AS total,
13
- pg_size_pretty(idx_bytes) AS idx,
14
- pg_size_pretty(toast_bytes) AS toast,
15
- pg_size_pretty(tbl_bytes) AS tbl
16
- FROM (
6
+ LOCK TABLE #{BetterRecord.db_audit_schema}.table_sizes;
7
+ TRUNCATE TABLE #{BetterRecord.db_audit_schema}.table_sizes;
8
+ INSERT INTO #{BetterRecord.db_audit_schema}.table_sizes (
17
9
  SELECT
18
10
  *,
19
- total_bytes - idx_bytes - COALESCE(toast_bytes,0) AS tbl_bytes
11
+ pg_size_pretty(total_bytes) AS total,
12
+ pg_size_pretty(idx_bytes) AS idx,
13
+ pg_size_pretty(toast_bytes) AS toast,
14
+ pg_size_pretty(tbl_bytes) AS tbl
20
15
  FROM (
21
- SELECT c.oid,nspname AS schema, relname AS name
22
- , c.reltuples AS apx_row_count
23
- , pg_total_relation_size(c.oid) AS total_bytes
24
- , pg_indexes_size(c.oid) AS idx_bytes
25
- , pg_total_relation_size(reltoastrelid) AS toast_bytes
26
- FROM pg_class c
27
- LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
28
- WHERE relkind = 'r'
29
- ) tmp_table_sizes
30
- ) tmp_table_sizes
31
- );
16
+ SELECT
17
+ *,
18
+ total_bytes - idx_bytes - COALESCE(toast_bytes,0) AS tbl_bytes
19
+ FROM (
20
+ SELECT c.oid,nspname AS schema, relname AS name
21
+ , c.reltuples AS row_estimate
22
+ , pg_total_relation_size(c.oid) AS total_bytes
23
+ , pg_indexes_size(c.oid) AS idx_bytes
24
+ , pg_total_relation_size(reltoastrelid) AS toast_bytes
25
+ FROM pg_class c
26
+ LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
27
+ WHERE relkind = 'r'
28
+ ) table_sizes
29
+ ) table_sizes
30
+ );
32
31
  COMMIT WORK;
33
32
  SQL
34
33
 
35
34
  # == Attributes ===========================================================
35
+ cattr_accessor :last_updated
36
36
  self.primary_key = :oid
37
37
  self.table_name = "#{BetterRecord.db_audit_schema}.table_sizes"
38
38
 
@@ -52,12 +52,14 @@ module BetterRecord
52
52
  super *args
53
53
  end
54
54
 
55
- def self.reload_data
56
- connection.execute LOAD_TABLE_DATA_SQL
55
+ def self.all
56
+ reload_data if last_updated.blank? || (super.first.last_updated > 1.hour.ago)
57
+ super
57
58
  end
58
59
 
59
- def self.tmp_table_exists?
60
- connection.query_values("SELECT temp_table_exists('tmp_table_sizes')").first
60
+ def self.reload_data
61
+ @@last_updated ||= Time.now
62
+ connection.execute UPDATE_TABLE_SIZES_SQL
61
63
  end
62
64
 
63
65
  # def self.default_print
@@ -0,0 +1,9 @@
1
+ class Date
2
+ def month_name
3
+ Date::MONTHNAMES[month]
4
+ end
5
+
6
+ def self.today
7
+ current
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ if defined?(Dkim) && ENV['DKIM_PATH'] && File.exists?(ENV['DKIM_PATH'])
2
+ Dkim::domain = ENV.fetch('DKIM_DOMAIN') { BetterRecord.app_domain_name }
3
+ Dkim::selector = `hostname`.strip.to_sym
4
+ Dkim::private_key = File.read(ENV['DKIM_PATH'])
5
+ # This will sign all ActionMailer deliveries
6
+ ActionMailer::Base.register_interceptor(Dkim::Interceptor)
7
+ end
@@ -0,0 +1,24 @@
1
+ if defined?(Redis) && defined?(Redis::Namespace)
2
+
3
+ begin
4
+ tmp_rds = Redis::Namespace.new("#{Rails.application.class.parent_name}::active_page", redis: Redis.new(url: ENV.fetch('REDIS_URL') { 'redis://localhost:6379/1' }))
5
+
6
+ tmp_rds.get('test')
7
+ rescue
8
+ if (!Rails.env.production? && !Boolean.parse(ENV.fetch('FORCE_REDIS') { false })) || Boolean.parse(ENV.fetch('ALLOW_FAKE_REDIS') { false })
9
+ require BetterRecord::Engine.root.join('lib', 'better_record', 'fake_redis')
10
+ puts "WARNING!!! Redis Server not found"
11
+ tmp_rds = BetterRecord::FakeRedis.new
12
+ else
13
+ raise
14
+ end
15
+ end
16
+
17
+ Rails.application.class.parent.const_set('REDIS', tmp_rds)
18
+
19
+ module Rails
20
+ def self.redis
21
+ Rails.application.class.parent.const_get('REDIS')
22
+ end
23
+ end
24
+ end
data/lib/better_record.rb CHANGED
@@ -6,17 +6,19 @@ module BetterRecord
6
6
  :db_audit_schema,
7
7
  :has_audits_by_default,
8
8
  :audit_relation_name,
9
- :layout_template
9
+ :layout_template,
10
+ :app_domain_name
10
11
  end
11
- self.default_polymorphic_method = :polymorphic_name
12
- self.db_audit_schema = ENV.fetch('DB_AUDIT_SCHEMA') { 'auditing' }
12
+ self.default_polymorphic_method = (ENV.fetch('BR_DEFAULT_POLYMORPHIC_METHOD') { :polymorphic_name }).to_sym
13
+ self.db_audit_schema = ENV.fetch('BR_DB_AUDIT_SCHEMA') { 'auditing' }
13
14
  self.has_audits_by_default = ActiveRecord::Type::Boolean.new.cast(ENV.fetch('BR_ADD_HAS_MANY') { false })
14
15
  self.audit_relation_name = (ENV.fetch('BR_AUDIT_RELATION_NAME') { 'audits' }).to_sym
15
16
  self.layout_template = (ENV.fetch('BR_LAYOUT_TEMPLATE') { 'better_record/layout' }).to_s
17
+ self.app_domain_name = (ENV.fetch('APP_DOMAIN_NAME') { 'non_existant_domain.com' }).to_s
16
18
  end
17
19
 
18
20
  Dir.glob("#{File.expand_path(__dir__)}/better_record/*").each do |d|
19
- require d
21
+ require d unless (d =~ /fake/)
20
22
  end
21
23
 
22
24
  ActiveSupport.on_load(:active_record) do
@@ -1,5 +1,12 @@
1
1
  module BetterRecord
2
2
  class Engine < ::Rails::Engine
3
3
  isolate_namespace BetterRecord
4
+ config.generators do |g|
5
+ g.templates.unshift File::expand_path("../templates", File.dirname(__FILE__))
6
+ g.test_framework :rspec, :fixture => false
7
+ g.fixture_replacement :factory_bot, :dir => 'spec/factories'
8
+ g.assets false
9
+ g.helper false
10
+ end
4
11
  end
5
12
  end
@@ -0,0 +1,94 @@
1
+ module BetterRecord
2
+ class FakeRedis
3
+ def data
4
+ @data ||= {}
5
+ end
6
+
7
+ def incr(key)
8
+ data[key] ||= 0
9
+ data[key] += 1
10
+ end
11
+
12
+ def decr(key)
13
+ data[key] ||= 0
14
+ data[key] -= 1
15
+ end
16
+
17
+ def set(key, val)
18
+ data[key] = val
19
+ end
20
+
21
+ def get(key)
22
+ data[key].dup
23
+ end
24
+
25
+ def lpush(key, val)
26
+ require_array
27
+ data[key].unshift val
28
+ data[key].size
29
+ end
30
+
31
+ def lrem(key, count, val)
32
+ require_array
33
+ start_idx = 0
34
+ arr = data[key]
35
+ removed = 0
36
+
37
+ if count == 0
38
+ removed = (arr.select {|v| v != val}).size
39
+ arr.select! {|v| v != val}
40
+ else
41
+ arr.reverse! if count < 0
42
+
43
+ count.abs.times do
44
+ removed += 1 unless arr.delete_at(arr.index(val) || arr.size).nil?
45
+ end
46
+
47
+ arr.reverse! if count < 0
48
+ end
49
+
50
+ data[key] = arr
51
+ removed
52
+ end
53
+
54
+ def lrange(key, start_idx, end_idx = -1)
55
+ data[key][start_idx..end_idx] || []
56
+ end
57
+
58
+ def rpush(key, val)
59
+ require_array
60
+ data[key] << val
61
+ data[key].size
62
+ end
63
+
64
+ def rpushx(key, val)
65
+ return 0 unless data[key]
66
+ rpush key, val
67
+ end
68
+
69
+ def rpop(key)
70
+ require_array
71
+ data[key].pop
72
+ end
73
+
74
+ def rpoplpush(one, two)
75
+ val = rpop(one)
76
+ lpush two, val
77
+ val
78
+ end
79
+
80
+ def method_missing
81
+ return nil
82
+ end
83
+
84
+ private
85
+ def require_array(key)
86
+ data[key] ||= []
87
+ raise_wrong_type unless data[key].is_a?(Array)
88
+ end
89
+
90
+ def raise_wrong_type
91
+ raise CommandError.new("WRONGTYPE Operation against a key holding the wrong kind of value")
92
+ end
93
+ end
94
+ end
@@ -1,3 +1,3 @@
1
1
  module BetterRecord
2
- VERSION = '0.1.1'
2
+ VERSION = '0.2.0'
3
3
  end
@@ -3,7 +3,13 @@ namespace :spec do
3
3
  task attributes: :environment do |t, args|
4
4
  raise 'No Model Given' unless ARGV[1].present?
5
5
  model_name = ARGV[1]
6
- file_path = Rails.root.join('spec', 'models', "#{model_name.underscore}_spec.rb")
6
+ root_path = ''
7
+ if model_name =~ /better\_?record/i
8
+ root_path = BetterRecord::Engine.root
9
+ else
10
+ root_path = Rails.root
11
+ end
12
+ file_path = root_path.join('spec', 'models', "#{model_name.underscore}_spec.rb")
7
13
  if File.exists?(file_path)
8
14
  file = File.read(file_path)
9
15
 
@@ -0,0 +1,6 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require_relative 'config/application'
5
+
6
+ Rails.application.load_tasks
@@ -0,0 +1,4 @@
1
+ //= link_tree ../images
2
+ //= link_directory ../javascripts .js
3
+ //= link_directory ../stylesheets .css
4
+ //= link better_record_manifest.js
@@ -0,0 +1,15 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file. JavaScript code in this file should be added after the last require_* statement.
9
+ //
10
+ // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require rails-ujs
14
+ //= require activestorage
15
+ //= require_tree .
@@ -0,0 +1,13 @@
1
+ // Action Cable provides the framework to deal with WebSockets in Rails.
2
+ // You can generate new channels where WebSocket features live using the `rails generate channel` command.
3
+ //
4
+ //= require action_cable
5
+ //= require_self
6
+ //= require_tree ./channels
7
+
8
+ (function() {
9
+ this.App || (this.App = {});
10
+
11
+ App.cable = ActionCable.createConsumer();
12
+
13
+ }).call(this);
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
+ * files in this directory. Styles in this file should be added after the last require_* statement.
11
+ * It is generally better to create a new file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,4 @@
1
+ module ApplicationCable
2
+ class Channel < ActionCable::Channel::Base
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module ApplicationCable
2
+ class Connection < ActionCable::Connection::Base
3
+ end
4
+ end
@@ -0,0 +1,2 @@
1
+ class ApplicationController < ActionController::Base
2
+ end
@@ -0,0 +1,2 @@
1
+ module ApplicationHelper
2
+ end
@@ -0,0 +1,2 @@
1
+ class ApplicationJob < ActiveJob::Base
2
+ end
@@ -0,0 +1,4 @@
1
+ class ApplicationMailer < ActionMailer::Base
2
+ default from: 'from@example.com'
3
+ layout 'mailer'
4
+ end
@@ -0,0 +1,3 @@
1
+ class ApplicationRecord < BetterRecord::Base
2
+ self.abstract_class = true
3
+ end