ros-apartment 2.7.2 → 2.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 51ac9b369655818ab39e99d729c9f6af3ce20090e01ba4d0f1fc71a184542f98
4
- data.tar.gz: 2c3aacd6fde07e50d9cf0b4344ef10e00cbf08704f1e6d5c71b4415b8c389bfd
3
+ metadata.gz: e12a4c472f448bc3f74307242fe0fb0929262c2a7fc5780996e8d49aa8421aff
4
+ data.tar.gz: 6bed24032f44c0669bca2fd92f0cd182f0d410752102493ff900709509d5f22e
5
5
  SHA512:
6
- metadata.gz: dd38c39ce27e90127acdf7a74ae47922b14e13494943fa8f1f70e7d7fa7db584177ea59a120fd5f7328d63e6c400240e1c566f662b02099bfef7918fc492d6ca
7
- data.tar.gz: 676637594e2ab218c24fe04eade88fe6f85ee69a3742ad029b2407e2499be0d22ef110b93075b9f590319e4623623a3390b7cade14e79ee26667fa2f5fed9e73
6
+ metadata.gz: a8ed3d29e8b56c61e2ca40134a421d7b6921e639e14f12ef492acb94bf7ef6b1df197b5f7f81541da0933acb946e4094080ee20e8b4c77e06e4b299acdb4ef1c
7
+ data.tar.gz: 18239dac52eb752c5d456c1004fe2f2424fa8dbe85bc20bfb5db45280a6df4948f5ae554f78f847698f74217809da4ebe549da5e91b9c2a69a910ef6a28d7b65
@@ -35,7 +35,29 @@ jobs:
35
35
 
36
36
  - name: Push changes
37
37
  if: env.push == 1
38
- uses: ad-m/github-push-action@master
39
- with:
40
- github_token: ${{ secrets.CHANGELOG_GITHUB_TOKEN }}
41
- branch: development
38
+ env:
39
+ # CI_USER: ${{ secrets.YOUR_GITHUB_USER }}
40
+ CI_TOKEN: ${{ secrets.CHANGELOG_GITHUB_TOKEN }}
41
+ run: |
42
+ git push "https://$GITHUB_ACTOR:$CI_TOKEN@github.com/$GITHUB_REPOSITORY.git" HEAD:master
43
+
44
+ # - name: Push changelog to master
45
+ # if: env.push == 1
46
+ # uses: ad-m/github-push-action@master
47
+ # with:
48
+ # github_token: ${{ secrets.CHANGELOG_GITHUB_TOKEN }}
49
+ # branch: master
50
+
51
+ # - name: Cherry-pick changelog to development
52
+ # if: env.push == 1
53
+ # env:
54
+ # ACTION_EMAIL: action@github.com
55
+ # ACTION_USERNAME: GitHub Action
56
+ # run: |
57
+ # git config --local user.email "$ACTION_EMAIL"
58
+ # git config --local user.name "$ACTION_USERNAME"
59
+ # commit_hash=`git show HEAD | egrep commit\ .+$ | cut -d' ' -f2`
60
+ # git checkout development
61
+ # git pull
62
+ # git cherry-pick $commit_hash
63
+ # git push
@@ -2,7 +2,31 @@
2
2
 
3
3
  ## [Unreleased](https://github.com/rails-on-services/apartment/tree/HEAD)
4
4
 
5
- [Full Changelog](https://github.com/rails-on-services/apartment/compare/v2.7.1...HEAD)
5
+ [Full Changelog](https://github.com/rails-on-services/apartment/compare/v2.7.2...HEAD)
6
+
7
+ **Implemented enhancements:**
8
+
9
+ - Uses a transaction to create a tenant [\#66](https://github.com/rails-on-services/apartment/issues/66)
10
+
11
+ **Fixed bugs:**
12
+
13
+ - Fix seeding errors [\#86](https://github.com/rails-on-services/apartment/issues/86)
14
+ - When tests run in a transaction, new tenants in tests fail to create [\#123](https://github.com/rails-on-services/apartment/issues/123)
15
+ - Reverted unsafe initializer - introduces the possibility of disabling the initial connection to the database via
16
+ environment variable. Relates to the following tickets/PRs:
17
+ - [#113](https://github.com/rails-on-services/apartment/issues/113)
18
+ - [#39](https://github.com/rails-on-services/apartment/pull/39)
19
+ - [#53](https://github.com/rails-on-services/apartment/pull/53)
20
+ - [#118](https://github.com/rails-on-services/apartment/pull/118)
21
+
22
+ **Closed issues:**
23
+
24
+ - Improve changelog automatic generation [\#98](https://github.com/rails-on-services/apartment/issues/98)
25
+ - Relaxes dependencies to allow rails 6.1 [\#121](https://github.com/rails-on-services/apartment/issues/121)
26
+
27
+ ## [v2.7.2](https://github.com/rails-on-services/apartment/tree/v2.7.2) (2020-07-17)
28
+
29
+ [Full Changelog](https://github.com/rails-on-services/apartment/compare/v2.7.1...v2.7.2)
6
30
 
7
31
  **Implemented enhancements:**
8
32
 
@@ -19,13 +43,21 @@
19
43
  - enhanced db:create task breaks plugins compatibility [\#82](https://github.com/rails-on-services/apartment/issues/82)
20
44
  - Support disabling of full\_migration\_on\_create [\#30](https://github.com/rails-on-services/apartment/issues/30)
21
45
 
46
+ **Merged pull requests:**
47
+
48
+ - \[Chore\] Fix Changelog github action [\#97](https://github.com/rails-on-services/apartment/pull/97) ([rpbaltazar](https://github.com/rpbaltazar))
49
+ - Prepare release - 2.7.2 [\#96](https://github.com/rails-on-services/apartment/pull/96) ([rpbaltazar](https://github.com/rpbaltazar))
50
+ - \[Resolves \#92\] tenant switch raises exception on first call [\#95](https://github.com/rails-on-services/apartment/pull/95) ([rpbaltazar](https://github.com/rpbaltazar))
51
+ - Dont use custom rubocop [\#94](https://github.com/rails-on-services/apartment/pull/94) ([rpbaltazar](https://github.com/rpbaltazar))
52
+ - \[Resolves \#80\] added changelog action [\#90](https://github.com/rails-on-services/apartment/pull/90) ([rpbaltazar](https://github.com/rpbaltazar))
53
+ - \[Resolves \#81\] check for var existence before [\#89](https://github.com/rails-on-services/apartment/pull/89) ([rpbaltazar](https://github.com/rpbaltazar))
54
+
22
55
  ## [v2.7.1](https://github.com/rails-on-services/apartment/tree/v2.7.1) (2020-06-27)
23
56
 
24
57
  [Full Changelog](https://github.com/rails-on-services/apartment/compare/v2.7.0...v2.7.1)
25
58
 
26
59
  **Merged pull requests:**
27
60
 
28
- - \[Resolves \#80\] added changelog action [\#90](https://github.com/rails-on-services/apartment/pull/90) ([rpbaltazar](https://github.com/rpbaltazar))
29
61
  - Prepare Release 2.7.1 [\#84](https://github.com/rails-on-services/apartment/pull/84) ([rpbaltazar](https://github.com/rpbaltazar))
30
62
  - \[Resolves \#82\] Enhanced db create task breaks plugins compatibility [\#83](https://github.com/rails-on-services/apartment/pull/83) ([rpbaltazar](https://github.com/rpbaltazar))
31
63
  - \[ci\] update rake [\#79](https://github.com/rails-on-services/apartment/pull/79) ([ahorek](https://github.com/ahorek))
@@ -67,6 +99,7 @@
67
99
 
68
100
  - db:rollback uses second latest migration for tenants [\#56](https://github.com/rails-on-services/apartment/issues/56)
69
101
  - rake db:setup tries to seed non existing tenant [\#52](https://github.com/rails-on-services/apartment/issues/52)
102
+ - Custom Console deprecation warning [\#37](https://github.com/rails-on-services/apartment/issues/37)
70
103
 
71
104
  **Merged pull requests:**
72
105
 
@@ -76,7 +109,6 @@
76
109
  - \[\#52\] enhance after db create [\#54](https://github.com/rails-on-services/apartment/pull/54) ([rpbaltazar](https://github.com/rpbaltazar))
77
110
  - fix init after reload on development [\#53](https://github.com/rails-on-services/apartment/pull/53) ([fsateler](https://github.com/fsateler))
78
111
  - fix: reset sequence\_name after tenant switch [\#51](https://github.com/rails-on-services/apartment/pull/51) ([fsateler](https://github.com/fsateler))
79
- - Add console welcome message [\#47](https://github.com/rails-on-services/apartment/pull/47) ([JeremiahChurch](https://github.com/JeremiahChurch))
80
112
  - Avoid early connection [\#39](https://github.com/rails-on-services/apartment/pull/39) ([fsateler](https://github.com/fsateler))
81
113
 
82
114
  ## [v2.6.0](https://github.com/rails-on-services/apartment/tree/v2.6.0) (2020-05-14)
@@ -88,13 +120,13 @@
88
120
  - Error Dropping Tenant [\#46](https://github.com/rails-on-services/apartment/issues/46)
89
121
  - After switch callback not working with nil argument [\#42](https://github.com/rails-on-services/apartment/issues/42)
90
122
  - Add tenant info to console boot? [\#41](https://github.com/rails-on-services/apartment/issues/41)
91
- - Custom Console deprecation warning [\#37](https://github.com/rails-on-services/apartment/issues/37)
92
123
  - Support configuration for skip checking of schema existence before switching [\#26](https://github.com/rails-on-services/apartment/issues/26)
93
124
 
94
125
  **Merged pull requests:**
95
126
 
96
127
  - \[Resolves \#37\] Custom console deprecation warning [\#49](https://github.com/rails-on-services/apartment/pull/49) ([rpbaltazar](https://github.com/rpbaltazar))
97
128
  - Prepare Release 2.6.0 [\#48](https://github.com/rails-on-services/apartment/pull/48) ([rpbaltazar](https://github.com/rpbaltazar))
129
+ - Add console welcome message [\#47](https://github.com/rails-on-services/apartment/pull/47) ([JeremiahChurch](https://github.com/JeremiahChurch))
98
130
  - \[Resolves \#26\] Support configuration for skip checking of schema existence before switching [\#45](https://github.com/rails-on-services/apartment/pull/45) ([rpbaltazar](https://github.com/rpbaltazar))
99
131
  - \[Resolves \#42\] After switch callback not working with nil argument [\#43](https://github.com/rails-on-services/apartment/pull/43) ([rpbaltazar](https://github.com/rpbaltazar))
100
132
 
data/README.md CHANGED
@@ -594,6 +594,16 @@ module Apartment
594
594
  end
595
595
  ```
596
596
 
597
+ ## Running rails console without a connection to the database
598
+
599
+ By default, once apartment starts, it establishes a connection to the database. It is possible to
600
+ disable this initial connection, by running with `APARTMENT_DISABLE_INIT` set to something:
601
+
602
+ ```shell
603
+ $ APARTMENT_DISABLE_INIT=true DATABASE_URL=postgresql://localhost:1234/buk_development bin/rails runner 'puts 1'
604
+ # 1
605
+ ```
606
+
597
607
  ## Contributing
598
608
 
599
609
  * In both `spec/dummy/config` and `spec/config`, you will see `database.yml.sample` files
@@ -6,7 +6,7 @@ require 'forwardable'
6
6
  require 'active_record'
7
7
  require 'apartment/tenant'
8
8
 
9
- require_relative 'apartment/active_record/log_subscriber'
9
+ require_relative 'apartment/log_subscriber'
10
10
 
11
11
  if ActiveRecord.version.release >= Gem::Version.new('6.0')
12
12
  require_relative 'apartment/active_record/connection_handling'
@@ -97,7 +97,23 @@ module Apartment
97
97
  end
98
98
 
99
99
  def create_tenant_command(conn, tenant)
100
- conn.execute(%(CREATE SCHEMA "#{tenant}"))
100
+ # NOTE: This was causing some tests to fail because of the database strategy for rspec
101
+ if ActiveRecord::Base.connection.open_transactions > 0
102
+ conn.execute(%(CREATE SCHEMA "#{tenant}"))
103
+ else
104
+ schema = %(BEGIN;
105
+ CREATE SCHEMA "#{tenant}";
106
+ COMMIT;)
107
+
108
+ conn.execute(schema)
109
+ end
110
+ rescue *rescuable_exceptions => e
111
+ rollback_transaction(conn)
112
+ raise e
113
+ end
114
+
115
+ def rollback_transaction(conn)
116
+ conn.execute("ROLLBACK;")
101
117
  end
102
118
 
103
119
  # Generate the final search path to set including persistent_schemas
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Apartment
4
+ class LogSubscriber < ActiveRecord::LogSubscriber
5
+ def sql(event)
6
+ super(event)
7
+ end
8
+
9
+ private
10
+
11
+ def debug(progname = nil, &block)
12
+ progname = " #{apartment_log}#{progname}" unless progname.nil?
13
+
14
+ super(progname, &block)
15
+ end
16
+
17
+ def apartment_log
18
+ database = color("[#{Apartment.connection.current_database}] ", ActiveSupport::LogSubscriber::MAGENTA, true)
19
+ schema = nil
20
+ unless Apartment.connection.schema_search_path.nil?
21
+ schema = color("[#{Apartment.connection.schema_search_path.tr('"', '')}] ",
22
+ ActiveSupport::LogSubscriber::YELLOW, true)
23
+ end
24
+ "#{database}#{schema}"
25
+ end
26
+ end
27
+ end
@@ -6,6 +6,7 @@ require 'apartment/reloader'
6
6
 
7
7
  module Apartment
8
8
  class Railtie < Rails::Railtie
9
+
9
10
  #
10
11
  # Set up our default config options
11
12
  # Do this before the app initializers run so we don't override custom settings
@@ -25,28 +26,32 @@ module Apartment
25
26
  ActiveRecord::Migrator.migrations_paths = Rails.application.paths['db/migrate'].to_a
26
27
  end
27
28
 
28
- # Make sure Apartment is reconfigured when the code is reloaded
29
+ # Hook into ActionDispatch::Reloader to ensure Apartment is properly initialized
30
+ # Note that this doens't entirely work as expected in Development, because this is called before classes are reloaded
31
+ # See the middleware/console declarations below to help with this. Hope to fix that soon.
32
+ #
29
33
  config.to_prepare do
30
- Apartment::Tenant.reload!
31
- end
34
+ next if ARGV.any? { |arg| arg =~ /\Aassets:(?:precompile|clean)\z/ }
35
+ next if ARGV.any? { |arg| arg == 'webpacker:compile' }
36
+ next if ENV["APARTMENT_DISABLE_INIT"]
32
37
 
33
- #
34
- # Ensure that Apartment::Tenant.init is called when
35
- # a new connection is requested.
36
- #
37
- module ApartmentInitializer
38
- def connection
39
- super.tap do
40
- Apartment::Tenant.init_once
38
+ begin
39
+ Apartment.connection_class.connection_pool.with_connection do
40
+ Apartment::Tenant.init
41
41
  end
42
+ rescue ::ActiveRecord::NoDatabaseError
43
+ # Since `db:create` and other tasks invoke this block from Rails 5.2.0,
44
+ # we need to swallow the error to execute `db:create` properly.
42
45
  end
46
+ end
43
47
 
44
- def arel_table
45
- Apartment::Tenant.init_once
46
- super
48
+ config.after_initialize do |app|
49
+ # NOTE: Load the custom log subscriber if enabled
50
+ if Apartment.active_record_log
51
+ ActiveSupport::Notifications.unsubscribe 'sql.active_record'
52
+ Apartment::LogSubscriber.attach_to :active_record
47
53
  end
48
54
  end
49
- ActiveRecord::Base.singleton_class.prepend ApartmentInitializer
50
55
 
51
56
  #
52
57
  # Ensure rake tasks are loaded
@@ -57,10 +62,8 @@ module Apartment
57
62
  end
58
63
 
59
64
  #
60
- # The following initializers are a workaround to the fact that I can't
61
- # properly hook into the rails reloader
62
- # Note this is technically valid for any environment where cache_classes
63
- # is false, for us, it's just development
65
+ # The following initializers are a workaround to the fact that I can't properly hook into the rails reloader
66
+ # Note this is technically valid for any environment where cache_classes is false, for us, it's just development
64
67
  #
65
68
  if Rails.env.development?
66
69
 
@@ -69,8 +72,7 @@ module Apartment
69
72
  app.config.middleware.use Apartment::Reloader
70
73
  end
71
74
 
72
- # Overrides reload! to also call Apartment::Tenant.init as well so that the
73
- # reloaded classes have the proper table_names
75
+ # Overrides reload! to also call Apartment::Tenant.init as well so that the reloaded classes have the proper table_names
74
76
  console do
75
77
  require 'apartment/console'
76
78
  end
@@ -29,5 +29,12 @@ module Apartment
29
29
  Note that your tenants currently haven't been migrated. You'll need to run `db:migrate` to rectify this.
30
30
  WARNING
31
31
  end
32
+
33
+ def self.create_tenant(tenant_name)
34
+ puts("Creating #{tenant_name} tenant")
35
+ Apartment::Tenant.create(tenant_name)
36
+ rescue Apartment::TenantExists => e
37
+ puts "Tried to create already existing tenant: #{e}"
38
+ end
32
39
  end
33
40
  end
@@ -15,20 +15,6 @@ module Apartment
15
15
 
16
16
  attr_writer :config
17
17
 
18
- def init_once
19
- return if @already_initialized
20
-
21
- # To avoid infinite loops in work init is doing,
22
- # we need to set @already_initialized to true
23
- # before init is called
24
- @already_initialized = true
25
- init
26
- end
27
-
28
- def reinitialize
29
- @already_initialized = false
30
- end
31
-
32
18
  # Fetch the proper multi-tenant adapter based on Rails config
33
19
  #
34
20
  # @return {subclass of Apartment::AbstractAdapter}
@@ -63,7 +49,6 @@ module Apartment
63
49
  #
64
50
  def reload!(config = nil)
65
51
  Thread.current[:apartment_adapter] = nil
66
- reinitialize
67
52
  @config = config
68
53
  end
69
54
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Apartment
4
- VERSION = '2.7.2'
4
+ VERSION = '2.8.0'
5
5
  end
@@ -10,12 +10,7 @@ apartment_namespace = namespace :apartment do
10
10
  Apartment::TaskHelper.warn_if_tenants_empty
11
11
 
12
12
  Apartment::TaskHelper.tenants.each do |tenant|
13
- begin
14
- puts("Creating #{tenant} tenant")
15
- Apartment::Tenant.create(tenant)
16
- rescue Apartment::TenantExists => e
17
- puts e.message
18
- end
13
+ Apartment::TaskHelper.create_tenant(tenant)
19
14
  end
20
15
  end
21
16
 
@@ -36,6 +31,7 @@ apartment_namespace = namespace :apartment do
36
31
  Apartment::TaskHelper.warn_if_tenants_empty
37
32
  Apartment::TaskHelper.each_tenant do |tenant|
38
33
  begin
34
+ Apartment::TaskHelper.create_tenant(tenant)
39
35
  puts("Migrating #{tenant} tenant")
40
36
  Apartment::Migrator.migrate tenant
41
37
  rescue Apartment::TenantNotFound => e
@@ -45,11 +41,12 @@ apartment_namespace = namespace :apartment do
45
41
  end
46
42
 
47
43
  desc 'Seed all tenants'
48
- task seed: :create do
44
+ task :seed do
49
45
  Apartment::TaskHelper.warn_if_tenants_empty
50
46
 
51
47
  Apartment::TaskHelper.each_tenant do |tenant|
52
48
  begin
49
+ Apartment::TaskHelper.create_tenant(tenant)
53
50
  puts("Seeding #{tenant} tenant")
54
51
  Apartment::Tenant.switch(tenant) do
55
52
  Apartment::Tenant.seed
@@ -27,7 +27,7 @@ Gem::Specification.new do |s|
27
27
  s.homepage = 'https://github.com/rails-on-services/apartment'
28
28
  s.licenses = ['MIT']
29
29
 
30
- s.add_dependency 'activerecord', '>= 5.0.0', '< 6.1'
30
+ s.add_dependency 'activerecord', '>= 5.0.0', '< 6.2'
31
31
  s.add_dependency 'parallel', '< 2.0'
32
32
  s.add_dependency 'public_suffix', '>= 2.0.5', '< 5.0'
33
33
  s.add_dependency 'rack', '>= 1.3.6', '< 3.0'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ros-apartment
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.7.2
4
+ version: 2.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Brunner
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2020-07-17 00:00:00.000000000 Z
13
+ date: 2020-12-16 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activerecord
@@ -21,7 +21,7 @@ dependencies:
21
21
  version: 5.0.0
22
22
  - - "<"
23
23
  - !ruby/object:Gem::Version
24
- version: '6.1'
24
+ version: '6.2'
25
25
  type: :runtime
26
26
  prerelease: false
27
27
  version_requirements: !ruby/object:Gem::Requirement
@@ -31,7 +31,7 @@ dependencies:
31
31
  version: 5.0.0
32
32
  - - "<"
33
33
  - !ruby/object:Gem::Version
34
- version: '6.1'
34
+ version: '6.2'
35
35
  - !ruby/object:Gem::Dependency
36
36
  name: parallel
37
37
  requirement: !ruby/object:Gem::Requirement
@@ -255,7 +255,6 @@ files:
255
255
  - lib/apartment.rb
256
256
  - lib/apartment/active_record/connection_handling.rb
257
257
  - lib/apartment/active_record/internal_metadata.rb
258
- - lib/apartment/active_record/log_subscriber.rb
259
258
  - lib/apartment/active_record/schema_migration.rb
260
259
  - lib/apartment/adapters/abstract_adapter.rb
261
260
  - lib/apartment/adapters/abstract_jdbc_adapter.rb
@@ -274,6 +273,7 @@ files:
274
273
  - lib/apartment/elevators/host.rb
275
274
  - lib/apartment/elevators/host_hash.rb
276
275
  - lib/apartment/elevators/subdomain.rb
276
+ - lib/apartment/log_subscriber.rb
277
277
  - lib/apartment/migrator.rb
278
278
  - lib/apartment/model.rb
279
279
  - lib/apartment/railtie.rb
@@ -1,44 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ActiveRecord
4
- # Supports the logging configuration to prepend the database and schema in the ActiveRecord log
5
- class LogSubscriber
6
- def apartment_log
7
- return unless Apartment.active_record_log
8
-
9
- database = color("[#{Apartment.connection.current_database}] ", ActiveSupport::LogSubscriber::MAGENTA, true)
10
- schema = nil
11
- unless Apartment.connection.schema_search_path.nil?
12
- schema = color("[#{Apartment.connection.schema_search_path.tr('"', '')}] ",
13
- ActiveSupport::LogSubscriber::YELLOW, true)
14
- end
15
- "#{database}#{schema}"
16
- end
17
-
18
- def payload_binds(binds, type_casted_binds)
19
- return unless (binds || []).empty?
20
-
21
- casted_params = type_casted_binds(type_casted_binds)
22
- ' ' + binds.zip(casted_params).map { |attr, value| render_bind(attr, value) }.inspect
23
- end
24
-
25
- def sql(event)
26
- self.class.runtime += event.duration
27
- return unless logger.debug?
28
-
29
- payload = event.payload
30
-
31
- return if IGNORE_PAYLOAD_NAMES.include?(payload[:name])
32
-
33
- name = "#{payload[:name]} (#{event.duration.round(1)}ms)"
34
- name = "CACHE #{name}" if payload[:cached]
35
- sql = payload[:sql]
36
- binds = payload_binds(payload[:binds], payload[:type_casted_binds])
37
-
38
- name = colorize_payload_name(name, payload[:name])
39
- sql = color(sql, sql_color(sql), true) if colorize_logging
40
-
41
- debug " #{apartment_log}#{name} #{sql}#{binds}"
42
- end
43
- end
44
- end