acts_as_table 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.yardopts +1 -0
- data/LICENSE +30 -0
- data/README.md +256 -0
- data/Rakefile +13 -0
- data/app/models/acts_as_table/belongs_to.rb +81 -0
- data/app/models/acts_as_table/column_model.rb +89 -0
- data/app/models/acts_as_table/foreign_key.rb +299 -0
- data/app/models/acts_as_table/foreign_key_map.rb +121 -0
- data/app/models/acts_as_table/has_many.rb +90 -0
- data/app/models/acts_as_table/has_many_target.rb +40 -0
- data/app/models/acts_as_table/lense.rb +131 -0
- data/app/models/acts_as_table/primary_key.rb +108 -0
- data/app/models/acts_as_table/record.rb +109 -0
- data/app/models/acts_as_table/record_error.rb +50 -0
- data/app/models/acts_as_table/record_model.rb +194 -0
- data/app/models/acts_as_table/row_model.rb +285 -0
- data/app/models/acts_as_table/table.rb +41 -0
- data/app/models/acts_as_table/value.rb +80 -0
- data/app/models/concerns/acts_as_table/record_model_class_methods.rb +554 -0
- data/app/models/concerns/acts_as_table/value_provider.rb +223 -0
- data/app/models/concerns/acts_as_table/value_provider_association_methods.rb +57 -0
- data/config/locales/en.yml +8 -0
- data/db/migrate/1_acts_as_table_migration.rb +186 -0
- data/lib/acts_as_table.rb +288 -0
- data/lib/acts_as_table/adapter.rb +81 -0
- data/lib/acts_as_table/engine.rb +14 -0
- data/lib/acts_as_table/headers.rb +196 -0
- data/lib/acts_as_table/mapper.rb +464 -0
- data/lib/acts_as_table/path.rb +157 -0
- data/lib/acts_as_table/reader.rb +149 -0
- data/lib/acts_as_table/version.rb +4 -0
- data/lib/acts_as_table/writer.rb +116 -0
- metadata +181 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e5e35bba33b684f86efbc6e25359aa1905e746349f8d620e5469979ff7b4ef73
|
4
|
+
data.tar.gz: c147a7b87ef0e222e755c0e91b3ea8c1c4f705ae67bc16c811c8069d09688acd
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: fd95f8e6caafb2fde253ce90a398fe7be97e42a5ab62f1c56b4fba341795f2f1d50b5c3f8dc1bb4747f2605d42a6123f4c3ccf103a2c9b66b3c6a7bd993fa22a
|
7
|
+
data.tar.gz: a5d3220b70279035c422e4e586f73c0f0579be8207a05b58c39c21dac8243a9a7eef7e0d657cce6fd5ed8c7e9b8b60d12d2b5f70319451f402596cf60c87edf5
|
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--markup markdown --markup-provider redcarpet --plugin activerecord --plugin activesupport-concern --plugin rails
|
data/LICENSE
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
Copyright (c) 2020, Battelle Memorial Institute
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
1. Battelle Memorial Institute (hereinafter Battelle) hereby grants permission
|
5
|
+
to any person or entity lawfully obtaining a copy of this software and
|
6
|
+
associated documentation files (hereinafter "the Software") to redistribute
|
7
|
+
and use the Software in source and binary forms, with or without
|
8
|
+
modification. Such person or entity may use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and may permit
|
10
|
+
others to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
* Redistributions of source code must retain the above copyright notice, this
|
13
|
+
list of conditions and the following disclaimers.
|
14
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
15
|
+
this list of conditions and the following disclaimer in the documentation
|
16
|
+
and/or other materials provided with the distribution.
|
17
|
+
* Other than as used herein, neither the name Battelle Memorial Institute or
|
18
|
+
Battelle may be used in any form whatsoever without the express written
|
19
|
+
consent of Battelle.
|
20
|
+
|
21
|
+
2. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
22
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
23
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
24
|
+
DISCLAIMED. IN NO EVENT SHALL BATTELLE OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
25
|
+
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
26
|
+
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
27
|
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
28
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
29
|
+
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
30
|
+
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.md
ADDED
@@ -0,0 +1,256 @@
|
|
1
|
+
# ActsAsTable
|
2
|
+
|
3
|
+
This is a Ruby on Rails plugin for working with tabular data.
|
4
|
+
|
5
|
+
* https://github.com/pnnl/acts_as_table
|
6
|
+
|
7
|
+
## Documentation
|
8
|
+
|
9
|
+
### ActsAsTable Table Specification Models
|
10
|
+
|
11
|
+
* {ActsAsTable::ColumnModel}
|
12
|
+
* {ActsAsTable::RowModel}
|
13
|
+
|
14
|
+
### ActsAsTable Record Specification Models
|
15
|
+
|
16
|
+
* {ActsAsTable::BelongsTo}
|
17
|
+
* {ActsAsTable::ForeignKey}
|
18
|
+
* {ActsAsTable::ForeignKeyMap}
|
19
|
+
* {ActsAsTable::HasMany}
|
20
|
+
* {ActsAsTable::HasManyTarget}
|
21
|
+
* {ActsAsTable::Lense}
|
22
|
+
* {ActsAsTable::PrimaryKey}
|
23
|
+
* {ActsAsTable::RecordModel}
|
24
|
+
* {ActsAsTable::RecordModelClassMethods} (concern)
|
25
|
+
* {ActsAsTable::ValueProvider} (concern)
|
26
|
+
* {ActsAsTable::ValueProviderAssociationMethods} (concern)
|
27
|
+
|
28
|
+
### ActsAsTable Table/Record Storage Models
|
29
|
+
|
30
|
+
* {ActsAsTable::Record}
|
31
|
+
* {ActsAsTable::RecordError}
|
32
|
+
* {ActsAsTable::Table}
|
33
|
+
* {ActsAsTable::Value}
|
34
|
+
|
35
|
+
### ActsAsTable Serialization
|
36
|
+
|
37
|
+
* {ActsAsTable::Headers}
|
38
|
+
* {ActsAsTable::Headers::Array}
|
39
|
+
* {ActsAsTable::Headers::Hash}
|
40
|
+
* {ActsAsTable::Reader}
|
41
|
+
* {ActsAsTable::Writer}
|
42
|
+
|
43
|
+
### ActsAsTable Serialization Formats
|
44
|
+
|
45
|
+
* [ActsAsTable::CSV](https://github.com/pnnl/acts_as_table_csv) (extension)
|
46
|
+
|
47
|
+
### ActsAsTable Utilities
|
48
|
+
|
49
|
+
* {ActsAsTable::Adapter}
|
50
|
+
* {ActsAsTable::Configuration}
|
51
|
+
* {ActsAsTable::Mapper}
|
52
|
+
* {ActsAsTable::Mapper::Base}
|
53
|
+
* {ActsAsTable::Mapper::BelongsTo}
|
54
|
+
* {ActsAsTable::Mapper::ForeignKey}
|
55
|
+
* {ActsAsTable::Mapper::HasAndBelongsToMany}
|
56
|
+
* {ActsAsTable::Mapper::HasMany}
|
57
|
+
* {ActsAsTable::Mapper::HasOne}
|
58
|
+
* {ActsAsTable::Mapper::Lense}
|
59
|
+
* {ActsAsTable::Mapper::PrimaryKey}
|
60
|
+
* {ActsAsTable::Mapper::RecordModel}
|
61
|
+
* {ActsAsTable::Mapper::RowModel}
|
62
|
+
* {ActsAsTable::Path}
|
63
|
+
|
64
|
+
## Dependencies
|
65
|
+
|
66
|
+
* [ActiveRecord](https://github.com/rails/rails/tree/master/activerecord) (>= 4.2, < 6.1)
|
67
|
+
|
68
|
+
## Installation
|
69
|
+
|
70
|
+
The recommended installation method is via [RubyGems](http://rubygems.org/).
|
71
|
+
To install the latest, official release of the ActsAsTable gem, do:
|
72
|
+
```bash
|
73
|
+
% [sudo] gem install acts_as_table
|
74
|
+
```
|
75
|
+
|
76
|
+
### Install ActsAsTable Migrations
|
77
|
+
|
78
|
+
If the ActsAsTable gem is being used as part of a Ruby on Rails application, do:
|
79
|
+
|
80
|
+
```bash
|
81
|
+
% rake acts_as_table:install:migrations
|
82
|
+
```
|
83
|
+
|
84
|
+
See documentation for {ActsAsTable.configure} for example of modifying the table names for the ActsAsTable model classes.
|
85
|
+
|
86
|
+
```bash
|
87
|
+
% rake db:migrate
|
88
|
+
```
|
89
|
+
|
90
|
+
## Examples
|
91
|
+
|
92
|
+
```ruby
|
93
|
+
require 'acts_as_table'
|
94
|
+
```
|
95
|
+
|
96
|
+
### Table/Record Specification for Preexisting Ruby on Rails Application
|
97
|
+
|
98
|
+
The preexisting Ruby on Rails application has the following model classes:
|
99
|
+
|
100
|
+
* `app/models/blog.rb`
|
101
|
+
|
102
|
+
```ruby
|
103
|
+
class Blog < ActiveRecord::Base
|
104
|
+
validates_presence_of :title
|
105
|
+
|
106
|
+
belongs_to :user, required: true
|
107
|
+
|
108
|
+
has_many :posts
|
109
|
+
end
|
110
|
+
```
|
111
|
+
|
112
|
+
* `app/models/post.rb`
|
113
|
+
|
114
|
+
```ruby
|
115
|
+
class Post < ActiveRecord::Base
|
116
|
+
validates_presence_of :title, :abstract
|
117
|
+
|
118
|
+
belongs_to :blog, required: true
|
119
|
+
end
|
120
|
+
```
|
121
|
+
|
122
|
+
* `app/models/user.rb`
|
123
|
+
|
124
|
+
```ruby
|
125
|
+
class User < ActiveRecord::Base
|
126
|
+
validates_presence_of :login, :email
|
127
|
+
|
128
|
+
has_many :blogs
|
129
|
+
end
|
130
|
+
```
|
131
|
+
|
132
|
+
The goal is to specify a table of instances of the `Post` class with the following structure:
|
133
|
+
|
134
|
+
| Protected | Protected | Public | Public | Public | Public | Public |
|
135
|
+
| :---: | :---: | :---: | :---: | :---: | :---: | :---: |
|
136
|
+
| User | User | Blog | Post | Post | Post | Post |
|
137
|
+
| Login Screen Name | Email Address | Title | Title | Abstract | Date Created | Date Modified |
|
138
|
+
| `post.blog.user.login` | `post.blog.user.email` | `post.blog.title` | `post.title` | `post.abstract` | `post.created_at` | `post.updated_at` |
|
139
|
+
|
140
|
+
The table has 3 header rows (viz., the metadata).
|
141
|
+
|
142
|
+
The non-header rows (viz., the data) correspond to arrays of Ruby objects (viz., the values), where the elements of the array are obtained by traversing paths of ActiveRecord associations that terminate with ActiveRecord columns or Ruby attribute accessors.
|
143
|
+
|
144
|
+
For example, the value of the "Protected,User,Login Screen Name" column is obtained by traversing the following path: `Post#blog` → `Blog#user` → `User#login`.
|
145
|
+
|
146
|
+
Multi-level headers (of arbitrary depth) and corresponding paths are specified using the {ActsAsTable::Path} class.
|
147
|
+
|
148
|
+
For example, the "Protected,User,Login Screen Name" is specified as follows:
|
149
|
+
```ruby
|
150
|
+
{
|
151
|
+
'Protected' => {
|
152
|
+
'User' => {
|
153
|
+
'Login Screen Name' => ActsAsTable::Path.new(Post).belongs_to(:blog).belongs_to(:user).attribute(:login),
|
154
|
+
},
|
155
|
+
},
|
156
|
+
}
|
157
|
+
```
|
158
|
+
|
159
|
+
To achieve the goal, first, seed the database with a new ActsAsTable row model.
|
160
|
+
|
161
|
+
* `db/seeds.rb`
|
162
|
+
|
163
|
+
```ruby
|
164
|
+
# This file should contain all the record creation needed to seed the database with its default values.
|
165
|
+
# The data can then be loaded with the rake db:seed (or created alongside the db with db:setup).
|
166
|
+
#
|
167
|
+
# Examples:
|
168
|
+
#
|
169
|
+
# cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }], without_protection: true)
|
170
|
+
# Mayor.create(name: 'Emanuel', city: cities.first)
|
171
|
+
|
172
|
+
ActsAsTable::RowModel.create(name: 'ActsAsTable row model for post->blog->user') do |row_model|
|
173
|
+
row_model.draw do
|
174
|
+
# @return [ActsAsTable::Path<Post>]
|
175
|
+
post_path = ActsAsTable::Path.new(Post)
|
176
|
+
|
177
|
+
# @return [ActsAsTable::Path<Blog>]
|
178
|
+
post_blog_path = post_path.belongs_to(:blog)
|
179
|
+
|
180
|
+
# @return [ActsAsTable::Path<User>]
|
181
|
+
post_blog_user_path = post_blog_path.belongs_to(:user)
|
182
|
+
|
183
|
+
self.columns = {
|
184
|
+
'Protected' => {
|
185
|
+
'User' => {
|
186
|
+
'Login Screen Name' => post_blog_user_path.attribute(:login),
|
187
|
+
'Email Address' => post_blog_user_path.attribute(:email),
|
188
|
+
},
|
189
|
+
},
|
190
|
+
'Public' => {
|
191
|
+
'Blog' => {
|
192
|
+
'Title' => post_blog_path.attribute(:title),
|
193
|
+
},
|
194
|
+
'Post' => {
|
195
|
+
'Title' => post_path.attribute(:title),
|
196
|
+
'Abstract' => post_path.attribute(:abstract),
|
197
|
+
'Date Created' => post_path.attribute(:created_at),
|
198
|
+
'Date Modified' => post_path.attribute(:updated_at),
|
199
|
+
},
|
200
|
+
},
|
201
|
+
}
|
202
|
+
|
203
|
+
# @return [ActsAsTable::Mapper::RecordModel<User>]
|
204
|
+
post_blog_user_model = model 'User' do
|
205
|
+
attribute :login, post_blog_user_path.attribute(:login)
|
206
|
+
attribute :email, post_blog_user_path.attribute(:email)
|
207
|
+
end
|
208
|
+
|
209
|
+
# @return [ActsAsTable::Mapper::RecordModel<Blog>]
|
210
|
+
post_blog_model = model 'Blog' do
|
211
|
+
attribute :title, post_blog_path.attribute(:title)
|
212
|
+
|
213
|
+
belongs_to :user, post_blog_user_model
|
214
|
+
end
|
215
|
+
|
216
|
+
# @return [ActsAsTable::Mapper::RecordModel<Post>]
|
217
|
+
post_model = model 'Post' do
|
218
|
+
attribute :title, post_path.attribute(:title)
|
219
|
+
attribute :abstract, post_path.attribute(:abstract)
|
220
|
+
attribute :created_at, post_path.attribute(:created_at)
|
221
|
+
attribute :updated_at, post_path.attribute(:updated_at)
|
222
|
+
|
223
|
+
belongs_to :blog, post_blog_model
|
224
|
+
end
|
225
|
+
|
226
|
+
self.root_model = post_model
|
227
|
+
end
|
228
|
+
end
|
229
|
+
```
|
230
|
+
|
231
|
+
Finally, serialize the data using the [ActsAsTable::CSV](https://github.com/pnnl/acts_as_table_csv) extension:
|
232
|
+
```ruby
|
233
|
+
# @return [ActsAsTable::RowModel]
|
234
|
+
row_model = ActsAsTable::RowModel.find(1)
|
235
|
+
|
236
|
+
# @return [ActiveRecord::Relation<Post>]
|
237
|
+
posts = Post.all
|
238
|
+
|
239
|
+
ActsAsTable.for(:csv).writer(row_model, $stdout) do |writer|
|
240
|
+
posts.each do |post|
|
241
|
+
writer << post
|
242
|
+
end
|
243
|
+
end
|
244
|
+
```
|
245
|
+
|
246
|
+
See documentation for [ActsAsTable::CSV](https://github.com/pnnl/acts_as_table_csv) extension for more parsing/serializing examples.
|
247
|
+
|
248
|
+
## Author
|
249
|
+
|
250
|
+
* [Mark Borkum](https://github.com/markborkum)
|
251
|
+
|
252
|
+
## License
|
253
|
+
|
254
|
+
This software is licensed under a 3-clause BSD license.
|
255
|
+
|
256
|
+
For more information, see the accompanying {file:LICENSE} file.
|
data/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
Bundler::GemHelper.install_tasks
|
8
|
+
|
9
|
+
require 'yard'
|
10
|
+
|
11
|
+
YARD::Rake::YardocTask.new do |t|
|
12
|
+
t.files = ['{app,lib}/**/*.rb']
|
13
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module ActsAsTable
|
2
|
+
# ActsAsTable singular macro association.
|
3
|
+
#
|
4
|
+
# @!attribute [rw] macro
|
5
|
+
# Returns the symbolic name for the macro for this ActsAsTable singular macro association.
|
6
|
+
#
|
7
|
+
# @note The macro must be either `:belongs_to` or `:has_one`.
|
8
|
+
#
|
9
|
+
# @return [String]
|
10
|
+
# @!attribute [rw] method_name
|
11
|
+
# Returns the method name for this ActsAsTable singular macro association.
|
12
|
+
#
|
13
|
+
# @return [String]
|
14
|
+
class BelongsTo < ::ActiveRecord::Base
|
15
|
+
# @!parse
|
16
|
+
# include ActsAsTable::ValueProvider
|
17
|
+
# include ActsAsTable::ValueProviderAssociationMethods
|
18
|
+
|
19
|
+
self.table_name = ActsAsTable.belongs_tos_table
|
20
|
+
|
21
|
+
# Returns the ActsAsTable row model for this ActsAsTable singular macro association.
|
22
|
+
belongs_to :row_model, **{
|
23
|
+
class_name: 'ActsAsTable::RowModel',
|
24
|
+
inverse_of: :belongs_tos,
|
25
|
+
required: true,
|
26
|
+
}
|
27
|
+
|
28
|
+
# Returns the source ActsAsTable record model for this ActsAsTable singular macro association.
|
29
|
+
belongs_to :source_record_model, **{
|
30
|
+
class_name: 'ActsAsTable::RecordModel',
|
31
|
+
inverse_of: :belongs_tos_as_source,
|
32
|
+
required: true,
|
33
|
+
}
|
34
|
+
|
35
|
+
# Returns the target ActsAsTable record model for this ActsAsTable singular macro association.
|
36
|
+
belongs_to :target_record_model, **{
|
37
|
+
class_name: 'ActsAsTable::RecordModel',
|
38
|
+
inverse_of: :belongs_tos_as_target,
|
39
|
+
required: true,
|
40
|
+
}
|
41
|
+
|
42
|
+
validates :macro, **{
|
43
|
+
inclusion: {
|
44
|
+
in: ['belongs_to', 'has_one'],
|
45
|
+
},
|
46
|
+
presence: true,
|
47
|
+
}
|
48
|
+
|
49
|
+
validates :method_name, **{
|
50
|
+
presence: true,
|
51
|
+
}
|
52
|
+
|
53
|
+
validate :macro_and_method_name_must_be_valid_association, **{
|
54
|
+
if: ::Proc.new { |belongs_to| belongs_to.macro.present? && belongs_to.method_name.present? },
|
55
|
+
}
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
# @return [void]
|
60
|
+
def macro_and_method_name_must_be_valid_association
|
61
|
+
self.source_record_model.try { |record_model| record_model.class_name.constantize rescue nil }.try { |source_klass|
|
62
|
+
# @return [ActiveRecord::Reflection::MacroReflection]
|
63
|
+
reflection = source_klass.reflect_on_association(self.method_name)
|
64
|
+
|
65
|
+
if reflection.nil?
|
66
|
+
self.errors.add('method_name', :required)
|
67
|
+
elsif self.macro.eql?(reflection.macro.to_s)
|
68
|
+
self.target_record_model.try { |record_model| record_model.class_name.constantize rescue nil }.try { |target_klass|
|
69
|
+
unless reflection.klass == target_klass
|
70
|
+
self.errors.add('target_record_model_id', :invalid)
|
71
|
+
end
|
72
|
+
}
|
73
|
+
else
|
74
|
+
self.errors.add('method_name', :invalid)
|
75
|
+
end
|
76
|
+
}
|
77
|
+
|
78
|
+
return
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module ActsAsTable
|
2
|
+
# ActsAsTable column model.
|
3
|
+
#
|
4
|
+
# @!attribute [rw] name
|
5
|
+
# Returns the name for this ActsAsTable column model.
|
6
|
+
#
|
7
|
+
# @return [String]
|
8
|
+
# @!attribute [rw] position
|
9
|
+
# Returns the position of this ActsAsTable column model.
|
10
|
+
#
|
11
|
+
# @return [Integer]
|
12
|
+
# @!attribute [rw] separator
|
13
|
+
# Returns the separator for the name of this ActsAsTable column model. By default, this is `,`.
|
14
|
+
#
|
15
|
+
# @return [String]
|
16
|
+
class ColumnModel < ::ActiveRecord::Base
|
17
|
+
# @!parse
|
18
|
+
# include ActsAsTable::ValueProvider
|
19
|
+
# include ActsAsTable::ValueProviderAssociationMethods
|
20
|
+
|
21
|
+
self.table_name = ActsAsTable.column_models_table
|
22
|
+
|
23
|
+
# Returns the ActsAsTable row model for this ActsAsTable column model.
|
24
|
+
belongs_to :row_model, **{
|
25
|
+
class_name: 'ActsAsTable::RowModel',
|
26
|
+
inverse_of: :column_models,
|
27
|
+
required: true,
|
28
|
+
}
|
29
|
+
|
30
|
+
# Returns the ActsAsTable foreign keys for this ActsAsTable column model.
|
31
|
+
has_many :foreign_keys, **{
|
32
|
+
autosave: true,
|
33
|
+
class_name: 'ActsAsTable::ForeignKey',
|
34
|
+
dependent: :nullify,
|
35
|
+
foreign_key: 'column_model_id',
|
36
|
+
inverse_of: :column_model,
|
37
|
+
validate: true,
|
38
|
+
}
|
39
|
+
|
40
|
+
# Returns the ActsAsTable attribute accessors for this ActsAsTable column model.
|
41
|
+
has_many :lenses, **{
|
42
|
+
autosave: true,
|
43
|
+
class_name: 'ActsAsTable::Lense',
|
44
|
+
dependent: :nullify,
|
45
|
+
foreign_key: 'column_model_id',
|
46
|
+
inverse_of: :column_model,
|
47
|
+
validate: true,
|
48
|
+
}
|
49
|
+
|
50
|
+
# Returns the ActsAsTable primary keys for this ActsAsTable column model.
|
51
|
+
has_many :primary_keys, **{
|
52
|
+
autosave: true,
|
53
|
+
class_name: 'ActsAsTable::PrimaryKey',
|
54
|
+
dependent: :nullify,
|
55
|
+
foreign_key: 'column_model_id',
|
56
|
+
inverse_of: :column_model,
|
57
|
+
validate: true,
|
58
|
+
}
|
59
|
+
|
60
|
+
# Returns the ActsAsTable values that have been provided by this ActsAsTable column model.
|
61
|
+
has_many :values, **{
|
62
|
+
class_name: 'ActsAsTable::Value',
|
63
|
+
dependent: :restrict_with_exception,
|
64
|
+
foreign_key: 'column_model_id',
|
65
|
+
inverse_of: :column_model,
|
66
|
+
}
|
67
|
+
|
68
|
+
validates :name, **{
|
69
|
+
presence: true,
|
70
|
+
}
|
71
|
+
|
72
|
+
validates :position, **{
|
73
|
+
numericality: {
|
74
|
+
greater_than_or_equal_to: 1,
|
75
|
+
only_integer: true,
|
76
|
+
},
|
77
|
+
presence: true,
|
78
|
+
uniqueness: {
|
79
|
+
scope: ['row_model_id'],
|
80
|
+
},
|
81
|
+
}
|
82
|
+
|
83
|
+
validates :separator, **{
|
84
|
+
length: {
|
85
|
+
minimum: 1,
|
86
|
+
},
|
87
|
+
}
|
88
|
+
end
|
89
|
+
end
|