sql_enum 0.1.17 → 0.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 56bcba219fbbe02cb0d5e65b1db5b1b348ceebb2
4
- data.tar.gz: 0e03f176ac9c33a8d99d2f6fef46e50bbc7cb29c
2
+ SHA256:
3
+ metadata.gz: 7ba5a5a0695bc9c11496ca90509646d98e2e005e7c89664aba78acb1de45d270
4
+ data.tar.gz: 1cb90fe77fcc9b7e2d84c0fe9b9b41ddee264de6e488d5de8dbc9462371a8ecd
5
5
  SHA512:
6
- metadata.gz: 93edc4d739b6d13decee145cee57acc07249acdb4b392e1779f10c9c26dc1aa7a395baa0a08f5d835c9879d6f343ef446660f3085d4b52f0e35fc522b63aca47
7
- data.tar.gz: 95dcb0ac0a2a33435745e7cd3d08fd0cd65b20f0a8a744f11767b6a5db79a137b40f3e07b0b730271d02f76a53c8ac5d92c551916571c834a37d69f8ed7e819c
6
+ metadata.gz: 795a28c30fc3fddb87865fc82325243c67a009694c409ffe880dace43c0d601cdcc32b4d9806a9d9c3220616dcc82be9b0e57ca8ccb3bb14c2d6562457c588a5
7
+ data.tar.gz: 67835417b809b63b7d97deb3531d059f3df63d1450406b0216cb81540a7276c691635126da7afdbf1dcf87fb128f7fe63cc8e196073fac55254e321ca1b66b58
data/.env ADDED
@@ -0,0 +1,3 @@
1
+ MYSQL_DATABASE=sql_enum_test
2
+ MYSQL_USER=sql_enum
3
+ MYSQL_PASSWORD=sql_enum
@@ -0,0 +1,16 @@
1
+ name: Tests
2
+
3
+ on:
4
+ push:
5
+ branches: [ master ]
6
+ pull_request:
7
+
8
+ jobs:
9
+ rspec:
10
+ runs-on: ubuntu-latest
11
+
12
+ steps:
13
+ - uses: actions/checkout@v2
14
+
15
+ - name: Test
16
+ run: docker-compose run --rm rspec
data/Dockerfile ADDED
@@ -0,0 +1,12 @@
1
+ FROM ruby:3.0
2
+
3
+ # throw errors if Gemfile has been modified since Gemfile.lock
4
+ RUN bundle config --global frozen 1
5
+
6
+ WORKDIR /usr/src/app
7
+
8
+ # Bundler caching
9
+ RUN mkdir -p lib/sql_enum
10
+ COPY lib/sql_enum/version.rb ./lib/sql_enum/
11
+ COPY sql_enum.gemspec Gemfile Gemfile.lock ./
12
+ RUN bundle install
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- source "https://rubygems.org"
1
+ source "https://gem-proxy.chime.com"
2
2
 
3
3
  git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
4
 
data/Gemfile.lock CHANGED
@@ -1,30 +1,32 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- sql_enum (0.1.4)
5
- activerecord (~> 5.0)
4
+ sql_enum (0.3.0)
5
+ activerecord (>= 5.0)
6
+ activesupport (>= 5.0)
7
+ mysql2
6
8
 
7
9
  GEM
8
- remote: https://rubygems.org/
10
+ remote: https://gem-proxy.chime.com/
9
11
  specs:
10
- activemodel (5.1.5)
11
- activesupport (= 5.1.5)
12
- activerecord (5.1.5)
13
- activemodel (= 5.1.5)
14
- activesupport (= 5.1.5)
15
- arel (~> 8.0)
16
- activesupport (5.1.5)
12
+ activemodel (6.1.4.1)
13
+ activesupport (= 6.1.4.1)
14
+ activerecord (6.1.4.1)
15
+ activemodel (= 6.1.4.1)
16
+ activesupport (= 6.1.4.1)
17
+ activesupport (6.1.4.1)
17
18
  concurrent-ruby (~> 1.0, >= 1.0.2)
18
- i18n (~> 0.7)
19
- minitest (~> 5.1)
20
- tzinfo (~> 1.1)
21
- arel (8.0.0)
22
- concurrent-ruby (1.0.5)
19
+ i18n (>= 1.6, < 2)
20
+ minitest (>= 5.1)
21
+ tzinfo (~> 2.0)
22
+ zeitwerk (~> 2.3)
23
+ concurrent-ruby (1.1.9)
23
24
  diff-lcs (1.3)
24
- i18n (0.9.5)
25
+ i18n (1.8.10)
25
26
  concurrent-ruby (~> 1.0)
26
- minitest (5.11.3)
27
- rake (10.5.0)
27
+ minitest (5.14.4)
28
+ mysql2 (0.5.3)
29
+ rake (13.0.3)
28
30
  rspec (3.7.0)
29
31
  rspec-core (~> 3.7.0)
30
32
  rspec-expectations (~> 3.7.0)
@@ -38,18 +40,18 @@ GEM
38
40
  diff-lcs (>= 1.2.0, < 2.0)
39
41
  rspec-support (~> 3.7.0)
40
42
  rspec-support (3.7.1)
41
- thread_safe (0.3.6)
42
- tzinfo (1.2.5)
43
- thread_safe (~> 0.1)
43
+ tzinfo (2.0.4)
44
+ concurrent-ruby (~> 1.0)
45
+ zeitwerk (2.5.1)
44
46
 
45
47
  PLATFORMS
46
48
  ruby
47
49
 
48
50
  DEPENDENCIES
49
- bundler (~> 1.16)
50
- rake (~> 10.0)
51
+ bundler
52
+ rake (~> 13.0)
51
53
  rspec (~> 3.0)
52
54
  sql_enum!
53
55
 
54
56
  BUNDLED WITH
55
- 1.16.1
57
+ 2.2.30
data/README.md CHANGED
@@ -48,9 +48,11 @@ class User < ActiveRecord::Base
48
48
  end
49
49
  ```
50
50
 
51
- ## TODO
51
+ ## Development
52
52
 
53
- * Enable passing `null` argument
53
+ ### Testing
54
+
55
+ Run `docker-compose run --rm rspec` to run the specs in a docker container alongside Mysql.
54
56
 
55
57
  ## Contributing
56
58
 
@@ -0,0 +1,23 @@
1
+ services:
2
+ rspec:
3
+ build: .
4
+ environment:
5
+ DATABASE_URL: "mysql2://${MYSQL_USER}:${MYSQL_PASSWORD}@mysql/${MYSQL_DATABASE}"
6
+ volumes:
7
+ - ./:/usr/src/app/
8
+ depends_on:
9
+ mysql:
10
+ condition: service_healthy
11
+ command: bundle exec rspec
12
+
13
+ mysql:
14
+ image: mysql:5.7
15
+ environment:
16
+ - MYSQL_ALLOW_EMPTY_PASSWORD=yes
17
+ - MYSQL_DATABASE
18
+ - MYSQL_USER
19
+ - MYSQL_PASSWORD
20
+ healthcheck:
21
+ test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"]
22
+ timeout: 20s
23
+ retries: 10
@@ -0,0 +1,3 @@
1
+ ActiveSupport.on_load(:active_record) do
2
+ extend SqlEnum::ClassMethods
3
+ end
@@ -0,0 +1,21 @@
1
+ module SqlEnum
2
+ module ClassMethods
3
+ def sql_enum(column_name, options = {})
4
+ # Query values
5
+ enum_column = EnumColumn.new(table_name, column_name)
6
+ values = enum_column.values.to_h { |value| [value.to_sym, value.to_s] }
7
+
8
+ # Check option defaults
9
+ prefix = options.fetch(:_prefix, !!SqlEnum.configuration&.default_prefix)
10
+ suffix = options.fetch(:_suffix, !!SqlEnum.configuration&.default_suffix)
11
+
12
+ # Define enum using Rails enum
13
+ enum(column_name => values, _prefix: prefix, _suffix: suffix)
14
+
15
+ # Override reader to return symbols
16
+ concerning "SqlEnum#{column_name.to_s.camelize}" do
17
+ define_method(column_name) { super()&.to_sym }
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,10 @@
1
+ module SqlEnum
2
+ class Configuration
3
+ attr_accessor :default_prefix, :default_suffix
4
+
5
+ def initialize
6
+ @default_prefix = false
7
+ @default_suffix = false
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SqlEnum
4
+ EnumColumn = Struct.new(:table_name, :column_name) do
5
+ def values
6
+ schema_values.to_s.scan(/\w+/).reject { |v| v == 'enum' }
7
+ end
8
+
9
+ private
10
+
11
+ def schema_values
12
+ ActiveRecord::Base.connection.exec_query(schema_values_query).rows.dig(0, 0)
13
+ end
14
+
15
+ def database_name
16
+ if ActiveRecord::Base.respond_to?(:connection_db_config)
17
+ ActiveRecord::Base.connection_db_config.configuration_hash[:database]
18
+ else
19
+ ActiveRecord::Base.connection_config.values_at(:database, :database_name).find(&:present?)
20
+ end
21
+ end
22
+
23
+ def schema_values_query
24
+ <<~EOSQL
25
+ SELECT column_type
26
+ FROM information_schema.COLUMNS
27
+ WHERE TABLE_SCHEMA = '#{database_name}'
28
+ AND TABLE_NAME = '#{table_name}'
29
+ AND COLUMN_NAME = '#{column_name}'
30
+ EOSQL
31
+ end
32
+ end
33
+ end
@@ -1,3 +1,3 @@
1
1
  module SqlEnum
2
- VERSION = "0.1.17"
2
+ VERSION = "0.3.0"
3
3
  end
data/lib/sql_enum.rb CHANGED
@@ -1,5 +1,3 @@
1
- require 'active_record'
2
-
3
1
  module SqlEnum
4
2
  class << self
5
3
  attr_accessor :configuration
@@ -9,22 +7,18 @@ module SqlEnum
9
7
  self.configuration ||= Configuration.new
10
8
  yield(configuration)
11
9
  end
12
-
13
- class Configuration
14
- attr_accessor :default_prefix, :default_suffix
15
-
16
- def initialize
17
- @default_prefix = false
18
- @default_suffix = false
19
- end
20
- end
21
10
  end
22
11
 
23
- require_relative 'active_record/enum/enum_type'
12
+ require 'active_record'
13
+ require 'active_support/core_ext/module/concerning'
14
+
24
15
  require_relative 'active_record/type/enum'
25
- require_relative 'active_record/enum_override'
26
- require_relative 'active_record/fixtures_override'
27
16
  require_relative 'active_record/connection_adapters/mysql2'
28
17
  require_relative 'active_record/connection_adapters/abstract_mysql'
29
18
  require_relative 'active_record/connection_adapters/mysql/column_methods'
30
- require_relative "sql_enum/version"
19
+
20
+ require_relative 'sql_enum/version'
21
+ require_relative 'sql_enum/configuration'
22
+ require_relative 'sql_enum/enum_column'
23
+ require_relative 'sql_enum/class_methods'
24
+ require_relative 'sql_enum/active_record'
data/sql_enum.gemspec CHANGED
@@ -1,6 +1,6 @@
1
-
2
1
  lib = File.expand_path("../lib", __FILE__)
3
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+
4
4
  require "sql_enum/version"
5
5
 
6
6
  Gem::Specification.new do |spec|
@@ -20,8 +20,11 @@ Gem::Specification.new do |spec|
20
20
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
21
  spec.require_paths = ["lib"]
22
22
 
23
- spec.add_dependency "activerecord"
24
- spec.add_development_dependency "bundler", "~> 1.16"
25
- spec.add_development_dependency "rake", "~> 10.0"
23
+ spec.add_dependency "activesupport", ">= 5.0"
24
+ spec.add_dependency "activerecord", ">= 5.0"
25
+ spec.add_dependency "mysql2"
26
+
27
+ spec.add_development_dependency "bundler"
28
+ spec.add_development_dependency "rake", "~> 13.0"
26
29
  spec.add_development_dependency "rspec", "~> 3.0"
27
30
  end
metadata CHANGED
@@ -1,17 +1,45 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sql_enum
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.17
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fletcher Fowler
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-08-29 00:00:00.000000000 Z
11
+ date: 2021-10-28 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '5.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '5.0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: activerecord
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '5.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '5.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: mysql2
15
43
  requirement: !ruby/object:Gem::Requirement
16
44
  requirements:
17
45
  - - ">="
@@ -28,30 +56,30 @@ dependencies:
28
56
  name: bundler
29
57
  requirement: !ruby/object:Gem::Requirement
30
58
  requirements:
31
- - - "~>"
59
+ - - ">="
32
60
  - !ruby/object:Gem::Version
33
- version: '1.16'
61
+ version: '0'
34
62
  type: :development
35
63
  prerelease: false
36
64
  version_requirements: !ruby/object:Gem::Requirement
37
65
  requirements:
38
- - - "~>"
66
+ - - ">="
39
67
  - !ruby/object:Gem::Version
40
- version: '1.16'
68
+ version: '0'
41
69
  - !ruby/object:Gem::Dependency
42
70
  name: rake
43
71
  requirement: !ruby/object:Gem::Requirement
44
72
  requirements:
45
73
  - - "~>"
46
74
  - !ruby/object:Gem::Version
47
- version: '10.0'
75
+ version: '13.0'
48
76
  type: :development
49
77
  prerelease: false
50
78
  version_requirements: !ruby/object:Gem::Requirement
51
79
  requirements:
52
80
  - - "~>"
53
81
  - !ruby/object:Gem::Version
54
- version: '10.0'
82
+ version: '13.0'
55
83
  - !ruby/object:Gem::Dependency
56
84
  name: rspec
57
85
  requirement: !ruby/object:Gem::Requirement
@@ -66,17 +94,20 @@ dependencies:
66
94
  - - "~>"
67
95
  - !ruby/object:Gem::Version
68
96
  version: '3.0'
69
- description:
97
+ description:
70
98
  email:
71
99
  - fletch@fzf.me
72
100
  executables: []
73
101
  extensions: []
74
102
  extra_rdoc_files: []
75
103
  files:
104
+ - ".env"
105
+ - ".github/workflows/tests.yml"
76
106
  - ".gitignore"
77
107
  - ".rspec"
78
108
  - ".travis.yml"
79
109
  - CODE_OF_CONDUCT.md
110
+ - Dockerfile
80
111
  - Gemfile
81
112
  - Gemfile.lock
82
113
  - LICENSE.txt
@@ -84,21 +115,23 @@ files:
84
115
  - Rakefile
85
116
  - bin/console
86
117
  - bin/setup
118
+ - docker-compose.yml
87
119
  - lib/active_record/connection_adapters/abstract_mysql.rb
88
120
  - lib/active_record/connection_adapters/mysql/column_methods.rb
89
121
  - lib/active_record/connection_adapters/mysql2.rb
90
- - lib/active_record/enum/enum_type.rb
91
- - lib/active_record/enum_override.rb
92
- - lib/active_record/fixtures_override.rb
93
122
  - lib/active_record/type/enum.rb
94
123
  - lib/sql_enum.rb
124
+ - lib/sql_enum/active_record.rb
125
+ - lib/sql_enum/class_methods.rb
126
+ - lib/sql_enum/configuration.rb
127
+ - lib/sql_enum/enum_column.rb
95
128
  - lib/sql_enum/version.rb
96
129
  - sql_enum.gemspec
97
130
  homepage: https://github.com/1debit/sql_enum
98
131
  licenses:
99
132
  - MIT
100
133
  metadata: {}
101
- post_install_message:
134
+ post_install_message:
102
135
  rdoc_options: []
103
136
  require_paths:
104
137
  - lib
@@ -113,9 +146,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
113
146
  - !ruby/object:Gem::Version
114
147
  version: '0'
115
148
  requirements: []
116
- rubyforge_project:
117
- rubygems_version: 2.5.2
118
- signing_key:
149
+ rubygems_version: 3.2.22
150
+ signing_key:
119
151
  specification_version: 4
120
152
  summary: Enable using native sql enums
121
153
  test_files: []
@@ -1,41 +0,0 @@
1
- module ActiveRecord
2
- module Enum
3
- class EnumType < Type::Value # :nodoc:
4
- delegate :type, to: :subtype
5
-
6
- def initialize(name, mapping, subtype)
7
- @name = name
8
- @mapping = mapping
9
- @subtype = subtype
10
- end
11
-
12
- def cast(value)
13
- return if value.blank?
14
-
15
- if valid?(value)
16
- value.to_sym
17
- else
18
- assert_valid_value(value)
19
- end
20
- end
21
-
22
- def deserialize(value)
23
- value&.to_sym
24
- end
25
-
26
- def serialize(value)
27
- value ? value.to_s : nil
28
- end
29
-
30
- def valid?(value)
31
- mapping.include?(value.to_s)
32
- end
33
-
34
- def assert_valid_value(value)
35
- unless value.blank? || valid?(value)
36
- raise ArgumentError, "'#{value}' is not a valid #{name}"
37
- end
38
- end
39
- end
40
- end
41
- end
@@ -1,79 +0,0 @@
1
- require 'active_record/enum'
2
-
3
- module ActiveRecord
4
- module Enum
5
- def sql_enum(name, options={})
6
- enum_prefix = options.delete(:_prefix)
7
- enum_suffix = options.delete(:_suffix)
8
-
9
- enum_prefix ||= name if SqlEnum.configuration&.default_prefix
10
- enum_suffix ||= name if SqlEnum.configuration&.default_suffix
11
-
12
- klass = self
13
- enum_values = Array.new
14
- name = name.to_sym
15
-
16
- detect_enum_conflict!(name, name.to_s.pluralize, true)
17
- klass.singleton_class.send(:define_method, name.to_s.pluralize) { enum_values.map(&:to_sym) }
18
-
19
- detect_enum_conflict!(name, name)
20
- detect_enum_conflict!(name, "#{name}=")
21
-
22
- attr = attribute_alias?(name) ? attribute_alias(name) : name
23
- decorate_attribute_type(attr, :enum) do |subtype|
24
- EnumType.new(attr, enum_values, subtype)
25
- end
26
-
27
- enum_values = values(name)
28
- enum_values.each do |value|
29
- if enum_prefix == true
30
- prefix = "#{name}_"
31
- elsif enum_prefix
32
- prefix = "#{enum_prefix}_"
33
- end
34
- if enum_suffix == true
35
- suffix = "_#{name}"
36
- elsif enum_suffix
37
- suffix = "_#{enum_suffix}"
38
- end
39
-
40
- value_method_name = "#{prefix}#{value}#{suffix}"
41
-
42
- # def active?() status == 0 end
43
- klass.send(:detect_enum_conflict!, name, "#{value_method_name}?")
44
- define_method("#{value_method_name}?") { self[attr] == value.to_s }
45
-
46
- # def active!() update! status: :active end
47
- klass.send(:detect_enum_conflict!, name, "#{value_method_name}!")
48
- define_method("#{value_method_name}!") { update!(attr => value) }
49
-
50
- # scope :active, -> { where status: 0 }
51
- klass.send(:detect_enum_conflict!, name, value_method_name, true)
52
- klass.scope value_method_name, -> { where(attr => value) }
53
- end
54
- defined_enums[name.to_s] = enum_values
55
- end
56
-
57
- def values(name)
58
- schema_values(name).to_s.scan(/\w+/).reject{|v| v == 'enum'}
59
- end
60
-
61
- def schema_values(name)
62
- ActiveRecord::Base.connection.exec_query(schema_values_query(name)).rows.dig(0,0)
63
- end
64
-
65
- def database_name
66
- ActiveRecord::Base.connection_config[:database]
67
- end
68
-
69
- def schema_values_query(name)
70
- %{
71
- SELECT column_type
72
- FROM information_schema.COLUMNS
73
- WHERE TABLE_SCHEMA = '#{database_name}'
74
- AND TABLE_NAME = '#{table_name}'
75
- AND COLUMN_NAME = '#{name}'
76
- }
77
- end
78
- end
79
- end
@@ -1,79 +0,0 @@
1
- require 'active_record/fixtures'
2
-
3
- module ActiveRecord
4
- class FixtureSet
5
- def table_rows
6
- now = config.default_timezone == :utc ? Time.now.utc : Time.now
7
-
8
- # allow a standard key to be used for doing defaults in YAML
9
- fixtures.delete('DEFAULTS')
10
-
11
- # track any join tables we need to insert later
12
- rows = Hash.new { |h,table| h[table] = [] }
13
-
14
- rows[table_name] = fixtures.map do |label, fixture|
15
- row = fixture.to_hash
16
-
17
- if model_class
18
- # fill in timestamp columns if they aren't specified and the model is set to record_timestamps
19
- if model_class.record_timestamps
20
- timestamp_column_names.each do |c_name|
21
- row[c_name] = now unless row.key?(c_name)
22
- end
23
- end
24
-
25
- # interpolate the fixture label
26
- row.each do |key, value|
27
- row[key] = value.gsub("$LABEL", label.to_s) if value.is_a?(String)
28
- end
29
-
30
- # generate a primary key if necessary
31
- if has_primary_key_column? && !row.include?(primary_key_name)
32
- row[primary_key_name] = ActiveRecord::FixtureSet.identify(label, primary_key_type)
33
- end
34
-
35
- # Resolve enums
36
- # model_class.defined_enums.each do |name, values|
37
- # if row.include?(name)
38
- # row[name] = values.fetch(row[name], row[name])
39
- # end
40
- # end
41
-
42
- # If STI is used, find the correct subclass for association reflection
43
- reflection_class =
44
- if row.include?(inheritance_column_name)
45
- row[inheritance_column_name].constantize rescue model_class
46
- else
47
- model_class
48
- end
49
-
50
- reflection_class._reflections.each_value do |association|
51
- case association.macro
52
- when :belongs_to
53
- # Do not replace association name with association foreign key if they are named the same
54
- fk_name = (association.options[:foreign_key] || "#{association.name}_id").to_s
55
-
56
- if association.name.to_s != fk_name && value = row.delete(association.name.to_s)
57
- if association.polymorphic? && value.sub!(/\s*\(([^\)]*)\)\s*$/, "")
58
- # support polymorphic belongs_to as "label (Type)"
59
- row[association.foreign_type] = $1
60
- end
61
-
62
- fk_type = reflection_class.type_for_attribute(fk_name).type
63
- row[fk_name] = ActiveRecord::FixtureSet.identify(value, fk_type)
64
- end
65
- when :has_many
66
- if association.options[:through]
67
- add_join_records(rows, row, HasManyThroughProxy.new(association))
68
- end
69
- end
70
- end
71
- end
72
-
73
- row
74
- end
75
- rows
76
- end
77
- end
78
- end
79
-