ransack 4.4.1 → 5.0.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 +4 -4
- data/README.md +2 -1
- data/lib/ransack/adapters/active_record/context.rb +12 -10
- data/lib/ransack/configuration.rb +38 -5
- data/lib/ransack/constants.rb +36 -11
- data/lib/ransack/context.rb +36 -4
- data/lib/ransack/helpers/form_builder.rb +1 -17
- data/lib/ransack/helpers/form_helper.rb +7 -7
- data/lib/ransack/nodes/attribute.rb +11 -2
- data/lib/ransack/nodes/condition.rb +106 -30
- data/lib/ransack/nodes/grouping.rb +23 -5
- data/lib/ransack/nodes/node.rb +13 -0
- data/lib/ransack/nodes/sort.rb +1 -2
- data/lib/ransack/nodes/value.rb +3 -1
- data/lib/ransack/predicate.rb +24 -3
- data/lib/ransack/search.rb +65 -22
- data/lib/ransack/version.rb +1 -1
- metadata +4 -60
- data/spec/console.rb +0 -13
- data/spec/factories/articles.rb +0 -7
- data/spec/factories/comments.rb +0 -7
- data/spec/factories/notes.rb +0 -13
- data/spec/factories/people.rb +0 -10
- data/spec/factories/tags.rb +0 -5
- data/spec/helpers/polyamorous_helper.rb +0 -13
- data/spec/helpers/ransack_helper.rb +0 -9
- data/spec/polyamorous/activerecord_compatibility_spec.rb +0 -15
- data/spec/polyamorous/join_association_spec.rb +0 -29
- data/spec/polyamorous/join_dependency_spec.rb +0 -80
- data/spec/polyamorous/join_spec.rb +0 -19
- data/spec/ransack/adapters/active_record/base_spec.rb +0 -943
- data/spec/ransack/adapters/active_record/context_spec.rb +0 -219
- data/spec/ransack/configuration_spec.rb +0 -201
- data/spec/ransack/helpers/form_builder_spec.rb +0 -169
- data/spec/ransack/helpers/form_helper_spec.rb +0 -1075
- data/spec/ransack/invalid_search_error_spec.rb +0 -27
- data/spec/ransack/nodes/condition_spec.rb +0 -333
- data/spec/ransack/nodes/grouping_spec.rb +0 -111
- data/spec/ransack/nodes/value_spec.rb +0 -126
- data/spec/ransack/predicate_spec.rb +0 -504
- data/spec/ransack/ransacker_spec.rb +0 -69
- data/spec/ransack/search_spec.rb +0 -821
- data/spec/ransack/translate_spec.rb +0 -16
- data/spec/spec_helper.rb +0 -52
- data/spec/support/en.yml +0 -18
- data/spec/support/schema.rb +0 -419
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
module Ransack
|
|
4
|
-
describe Translate do
|
|
5
|
-
describe '.attribute' do
|
|
6
|
-
it 'translate namespaced attribute like AR does' do
|
|
7
|
-
ar_translation = ::Namespace::Article.human_attribute_name(:title)
|
|
8
|
-
ransack_translation = Ransack::Translate.attribute(
|
|
9
|
-
:title,
|
|
10
|
-
context: ::Namespace::Article.ransack.context
|
|
11
|
-
)
|
|
12
|
-
expect(ransack_translation).to eq ar_translation
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
end
|
data/spec/spec_helper.rb
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
require 'ransack'
|
|
2
|
-
require 'factory_bot'
|
|
3
|
-
require 'faker'
|
|
4
|
-
require 'action_controller'
|
|
5
|
-
require 'ransack/helpers'
|
|
6
|
-
require 'pry'
|
|
7
|
-
require 'simplecov'
|
|
8
|
-
require 'byebug'
|
|
9
|
-
require 'rspec'
|
|
10
|
-
|
|
11
|
-
SimpleCov.start
|
|
12
|
-
I18n.enforce_available_locales = false
|
|
13
|
-
Time.zone = 'Eastern Time (US & Canada)'
|
|
14
|
-
I18n.load_path += Dir[File.join(File.dirname(__FILE__), 'support', '*.yml')]
|
|
15
|
-
|
|
16
|
-
Dir[File.expand_path('../{helpers,support,factories}/*.rb', __FILE__)]
|
|
17
|
-
.each { |f| require f }
|
|
18
|
-
|
|
19
|
-
Faker::Config.random = Random.new(0)
|
|
20
|
-
|
|
21
|
-
RSpec.configure do |config|
|
|
22
|
-
config.alias_it_should_behave_like_to :it_has_behavior, 'has behavior'
|
|
23
|
-
|
|
24
|
-
config.include FactoryBot::Syntax::Methods
|
|
25
|
-
|
|
26
|
-
config.before(:suite) do
|
|
27
|
-
message = "Running Ransack specs with #{
|
|
28
|
-
ActiveRecord::Base.connection.adapter_name
|
|
29
|
-
}, Active Record #{::ActiveRecord::VERSION::STRING}, Arel #{Arel::VERSION
|
|
30
|
-
} and Ruby #{RUBY_VERSION}"
|
|
31
|
-
line = '=' * message.length
|
|
32
|
-
puts line, message, line
|
|
33
|
-
Schema.create
|
|
34
|
-
SubDB::Schema.create if defined?(SubDB)
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
config.include RansackHelper
|
|
38
|
-
config.include PolyamorousHelper
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
RSpec::Matchers.define :be_like do |expected|
|
|
42
|
-
match do |actual|
|
|
43
|
-
actual.gsub(/^\s+|\s+$/, '').gsub(/\s+/, ' ').strip ==
|
|
44
|
-
expected.gsub(/^\s+|\s+$/, '').gsub(/\s+/, ' ').strip
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
RSpec::Matchers.define :have_attribute_method do |expected|
|
|
49
|
-
match do |actual|
|
|
50
|
-
actual.attribute_method?(expected)
|
|
51
|
-
end
|
|
52
|
-
end
|
data/spec/support/en.yml
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
en:
|
|
2
|
-
attributes:
|
|
3
|
-
id: 'id'
|
|
4
|
-
ransack:
|
|
5
|
-
attributes:
|
|
6
|
-
person:
|
|
7
|
-
name: Full Name
|
|
8
|
-
only_admin: admin uSer Only
|
|
9
|
-
salary: wages
|
|
10
|
-
awesome: ransack is really awesome
|
|
11
|
-
article:
|
|
12
|
-
body: maiN BoDy
|
|
13
|
-
activerecord:
|
|
14
|
-
attributes:
|
|
15
|
-
namespace/article:
|
|
16
|
-
title: AR Namespaced Title
|
|
17
|
-
namespace_article:
|
|
18
|
-
title: Old Ransack Namespaced Title
|
data/spec/support/schema.rb
DELETED
|
@@ -1,419 +0,0 @@
|
|
|
1
|
-
require 'active_record'
|
|
2
|
-
require 'activerecord-postgis-adapter'
|
|
3
|
-
|
|
4
|
-
case ENV['DB'].try(:downcase)
|
|
5
|
-
when 'mysql', 'mysql2'
|
|
6
|
-
# To test with MySQL: `DB=mysql bundle exec rake spec`
|
|
7
|
-
ActiveRecord::Base.establish_connection(
|
|
8
|
-
adapter: 'mysql2',
|
|
9
|
-
database: 'ransack',
|
|
10
|
-
username: ENV.fetch("MYSQL_USERNAME") { "root" },
|
|
11
|
-
password: ENV.fetch("MYSQL_PASSWORD") { "" },
|
|
12
|
-
encoding: 'utf8'
|
|
13
|
-
)
|
|
14
|
-
when 'pg', 'postgres', 'postgresql'
|
|
15
|
-
# To test with PostgreSQL: `DB=postgresql bundle exec rake spec`
|
|
16
|
-
ActiveRecord::Base.establish_connection(
|
|
17
|
-
adapter: 'postgresql',
|
|
18
|
-
database: 'ransack',
|
|
19
|
-
username: ENV.fetch("DATABASE_USERNAME") { "postgres" },
|
|
20
|
-
password: ENV.fetch("DATABASE_PASSWORD") { "" },
|
|
21
|
-
host: ENV.fetch("DATABASE_HOST") { "localhost" },
|
|
22
|
-
min_messages: 'warning'
|
|
23
|
-
)
|
|
24
|
-
when 'postgis'
|
|
25
|
-
# To test with PostGIS: `DB=postgis bundle exec rake spec`
|
|
26
|
-
ActiveRecord::Base.establish_connection(
|
|
27
|
-
adapter: 'postgis',
|
|
28
|
-
postgis_extension: 'postgis',
|
|
29
|
-
database: 'ransack',
|
|
30
|
-
username: ENV.fetch("DATABASE_USERNAME") { "postgres" },
|
|
31
|
-
password: ENV.fetch("DATABASE_PASSWORD") { "" },
|
|
32
|
-
host: ENV.fetch("DATABASE_HOST") { "localhost" },
|
|
33
|
-
min_messages: 'warning'
|
|
34
|
-
)
|
|
35
|
-
else
|
|
36
|
-
# Otherwise, assume SQLite3: `bundle exec rake spec`
|
|
37
|
-
ActiveRecord::Base.establish_connection(
|
|
38
|
-
adapter: 'sqlite3',
|
|
39
|
-
database: ':memory:'
|
|
40
|
-
)
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
# This is just a test app with no sensitive data, so we explicitly allowlist all
|
|
44
|
-
# attributes and associations for search. In general, end users should
|
|
45
|
-
# explicitly authorize each model, but this shows a way to configure the
|
|
46
|
-
# unrestricted default behavior of versions prior to Ransack 4.
|
|
47
|
-
#
|
|
48
|
-
class ApplicationRecord < ActiveRecord::Base
|
|
49
|
-
self.abstract_class = true
|
|
50
|
-
|
|
51
|
-
def self.ransackable_attributes(auth_object = nil)
|
|
52
|
-
authorizable_ransackable_attributes
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
def self.ransackable_associations(auth_object = nil)
|
|
56
|
-
authorizable_ransackable_associations
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
class Person < ApplicationRecord
|
|
61
|
-
default_scope { order(id: :desc) }
|
|
62
|
-
belongs_to :parent, class_name: 'Person', foreign_key: :parent_id
|
|
63
|
-
has_many :children, class_name: 'Person', foreign_key: :parent_id
|
|
64
|
-
has_many :articles
|
|
65
|
-
has_many :story_articles
|
|
66
|
-
|
|
67
|
-
has_many :published_articles, ->{ where(published: true) },
|
|
68
|
-
class_name: "Article"
|
|
69
|
-
has_many :comments
|
|
70
|
-
has_many :authored_article_comments, through: :articles,
|
|
71
|
-
source: :comments, foreign_key: :person_id
|
|
72
|
-
has_many :notes, as: :notable
|
|
73
|
-
|
|
74
|
-
scope :restricted, lambda { where("restricted = 1") }
|
|
75
|
-
scope :active, lambda { where("active = 1") }
|
|
76
|
-
scope :over_age, lambda { |y| where(["age > ?", y]) }
|
|
77
|
-
scope :of_age, lambda { |of_age|
|
|
78
|
-
of_age ? where("age >= ?", 18) : where("age < ?", 18)
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
scope :sort_by_reverse_name_asc, lambda { order(Arel.sql("REVERSE(name) ASC")) }
|
|
82
|
-
scope :sort_by_reverse_name_desc, lambda { order("REVERSE(name) DESC") }
|
|
83
|
-
|
|
84
|
-
alias_attribute :full_name, :name
|
|
85
|
-
|
|
86
|
-
ransack_alias :term, :name_or_email
|
|
87
|
-
ransack_alias :daddy, :parent_name
|
|
88
|
-
|
|
89
|
-
ransacker :reversed_name, formatter: proc { |v| v.reverse } do |parent|
|
|
90
|
-
parent.table[:name]
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
ransacker :array_people_ids,
|
|
94
|
-
formatter: proc { |v| Person.first(2).map(&:id) } do |parent|
|
|
95
|
-
parent.table[:id]
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
ransacker :array_where_people_ids,
|
|
99
|
-
formatter: proc { |v| Person.where(id: v).map(&:id) } do |parent|
|
|
100
|
-
parent.table[:id]
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
ransacker :array_people_names,
|
|
104
|
-
formatter: proc { |v| Person.first(2).map { |p| p.id.to_s } } do |parent|
|
|
105
|
-
parent.table[:name]
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
ransacker :array_where_people_names,
|
|
109
|
-
formatter: proc { |v| Person.where(id: v).map { |p| p.id.to_s } } do |parent|
|
|
110
|
-
parent.table[:name]
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
ransacker :doubled_name do |parent|
|
|
114
|
-
Arel::Nodes::InfixOperation.new(
|
|
115
|
-
'||', parent.table[:name], parent.table[:name]
|
|
116
|
-
)
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
ransacker :sql_literal_id, type: :integer do
|
|
120
|
-
Arel.sql('people.id')
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
ransacker :name_case_insensitive, type: :string do
|
|
124
|
-
arel_table[:name].lower
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
ransacker :with_arguments, args: [:parent, :ransacker_args] do |parent, args|
|
|
128
|
-
min, max = args
|
|
129
|
-
query = <<-SQL
|
|
130
|
-
(SELECT MAX(articles.title)
|
|
131
|
-
FROM articles
|
|
132
|
-
WHERE articles.person_id = people.id
|
|
133
|
-
AND LENGTH(articles.body) BETWEEN #{min} AND #{max}
|
|
134
|
-
GROUP BY articles.person_id
|
|
135
|
-
)
|
|
136
|
-
SQL
|
|
137
|
-
.squish
|
|
138
|
-
Arel.sql(query)
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
ransacker :article_tags, formatter: proc { |id|
|
|
142
|
-
if Tag.exists?(id)
|
|
143
|
-
joins(articles: :tags)
|
|
144
|
-
.where(tags: { id: id })
|
|
145
|
-
.distinct
|
|
146
|
-
.select(:id).arel
|
|
147
|
-
end
|
|
148
|
-
} do |parent|
|
|
149
|
-
parent.table[:id]
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
def self.ransackable_attributes(auth_object = nil)
|
|
153
|
-
if auth_object == :admin
|
|
154
|
-
authorizable_ransackable_attributes - ['only_sort']
|
|
155
|
-
else
|
|
156
|
-
authorizable_ransackable_attributes - ['only_sort', 'only_admin']
|
|
157
|
-
end
|
|
158
|
-
end
|
|
159
|
-
|
|
160
|
-
def self.ransortable_attributes(auth_object = nil)
|
|
161
|
-
if auth_object == :admin
|
|
162
|
-
column_names + _ransackers.keys - ['only_search']
|
|
163
|
-
else
|
|
164
|
-
column_names + _ransackers.keys - ['only_search', 'only_admin']
|
|
165
|
-
end
|
|
166
|
-
end
|
|
167
|
-
end
|
|
168
|
-
|
|
169
|
-
class Musician < Person
|
|
170
|
-
end
|
|
171
|
-
|
|
172
|
-
class Article < ApplicationRecord
|
|
173
|
-
belongs_to :person
|
|
174
|
-
has_many :comments
|
|
175
|
-
has_and_belongs_to_many :tags
|
|
176
|
-
has_many :notes, as: :notable
|
|
177
|
-
has_many :recent_notes, as: :notable
|
|
178
|
-
|
|
179
|
-
alias_attribute :content, :body
|
|
180
|
-
|
|
181
|
-
default_scope { where("'default_scope' = 'default_scope'") }
|
|
182
|
-
scope :latest_comment_cont, lambda { |msg|
|
|
183
|
-
join = <<-SQL
|
|
184
|
-
(LEFT OUTER JOIN (
|
|
185
|
-
SELECT
|
|
186
|
-
comments.*,
|
|
187
|
-
row_number() OVER (PARTITION BY comments.article_id ORDER BY comments.id DESC) AS rownum
|
|
188
|
-
FROM comments
|
|
189
|
-
) AS latest_comment
|
|
190
|
-
ON latest_comment.article_id = article.id
|
|
191
|
-
AND latest_comment.rownum = 1
|
|
192
|
-
)
|
|
193
|
-
SQL
|
|
194
|
-
.squish
|
|
195
|
-
|
|
196
|
-
joins(join).where("latest_comment.body ILIKE ?", "%#{msg}%")
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
ransacker :title_type, formatter: lambda { |tuples|
|
|
200
|
-
title, type = JSON.parse(tuples)
|
|
201
|
-
Arel::Nodes::Grouping.new(
|
|
202
|
-
[
|
|
203
|
-
Arel::Nodes.build_quoted(title),
|
|
204
|
-
Arel::Nodes.build_quoted(type)
|
|
205
|
-
]
|
|
206
|
-
)
|
|
207
|
-
} do |_parent|
|
|
208
|
-
articles = Article.arel_table
|
|
209
|
-
Arel::Nodes::Grouping.new(
|
|
210
|
-
%i[title type].map do |field|
|
|
211
|
-
Arel::Nodes::NamedFunction.new(
|
|
212
|
-
'COALESCE',
|
|
213
|
-
[
|
|
214
|
-
Arel::Nodes::NamedFunction.new('TRIM', [articles[field]]),
|
|
215
|
-
Arel::Nodes.build_quoted('')
|
|
216
|
-
]
|
|
217
|
-
)
|
|
218
|
-
end
|
|
219
|
-
)
|
|
220
|
-
end
|
|
221
|
-
end
|
|
222
|
-
|
|
223
|
-
class StoryArticle < Article
|
|
224
|
-
end
|
|
225
|
-
|
|
226
|
-
class Recommendation < ApplicationRecord
|
|
227
|
-
belongs_to :person
|
|
228
|
-
belongs_to :target_person, class_name: 'Person'
|
|
229
|
-
belongs_to :article
|
|
230
|
-
end
|
|
231
|
-
|
|
232
|
-
module Namespace
|
|
233
|
-
class Article < ::Article
|
|
234
|
-
|
|
235
|
-
end
|
|
236
|
-
end
|
|
237
|
-
|
|
238
|
-
module Namespace
|
|
239
|
-
class Article < ::Article
|
|
240
|
-
|
|
241
|
-
end
|
|
242
|
-
end
|
|
243
|
-
|
|
244
|
-
class Comment < ApplicationRecord
|
|
245
|
-
belongs_to :article
|
|
246
|
-
belongs_to :person
|
|
247
|
-
has_and_belongs_to_many :tags
|
|
248
|
-
|
|
249
|
-
default_scope { where(disabled: false) }
|
|
250
|
-
end
|
|
251
|
-
|
|
252
|
-
class Tag < ApplicationRecord
|
|
253
|
-
has_and_belongs_to_many :articles
|
|
254
|
-
has_and_belongs_to_many :comments
|
|
255
|
-
end
|
|
256
|
-
|
|
257
|
-
class Note < ApplicationRecord
|
|
258
|
-
belongs_to :notable, polymorphic: true
|
|
259
|
-
end
|
|
260
|
-
|
|
261
|
-
class RecentNote < ApplicationRecord
|
|
262
|
-
DEFAULT_NOTABLE_ID = 1
|
|
263
|
-
self.table_name = "notes"
|
|
264
|
-
default_scope { where(notable_id: DEFAULT_NOTABLE_ID) }
|
|
265
|
-
|
|
266
|
-
belongs_to :notable, polymorphic: true
|
|
267
|
-
end
|
|
268
|
-
|
|
269
|
-
class Account < ApplicationRecord
|
|
270
|
-
belongs_to :agent_account, class_name: "Account"
|
|
271
|
-
belongs_to :trade_account, class_name: "Account"
|
|
272
|
-
end
|
|
273
|
-
|
|
274
|
-
class Address < ApplicationRecord
|
|
275
|
-
has_one :organization
|
|
276
|
-
end
|
|
277
|
-
|
|
278
|
-
class Organization < ApplicationRecord
|
|
279
|
-
belongs_to :address
|
|
280
|
-
has_many :employees
|
|
281
|
-
end
|
|
282
|
-
|
|
283
|
-
class Employee < ApplicationRecord
|
|
284
|
-
belongs_to :organization
|
|
285
|
-
has_one :address, through: :organization
|
|
286
|
-
end
|
|
287
|
-
|
|
288
|
-
module Schema
|
|
289
|
-
def self.create
|
|
290
|
-
ActiveRecord::Migration.verbose = false
|
|
291
|
-
|
|
292
|
-
ActiveRecord::Schema.define do
|
|
293
|
-
create_table :people, force: true do |t|
|
|
294
|
-
t.integer :parent_id
|
|
295
|
-
t.string :name
|
|
296
|
-
t.string :email
|
|
297
|
-
t.string :only_search
|
|
298
|
-
t.string :only_sort
|
|
299
|
-
t.string :only_admin
|
|
300
|
-
t.string :new_start
|
|
301
|
-
t.string :stop_end
|
|
302
|
-
t.integer :salary
|
|
303
|
-
t.date :life_start
|
|
304
|
-
t.boolean :awesome, default: false
|
|
305
|
-
t.boolean :terms_and_conditions, default: false
|
|
306
|
-
t.boolean :true_or_false, default: true
|
|
307
|
-
t.timestamps null: false
|
|
308
|
-
end
|
|
309
|
-
|
|
310
|
-
create_table :articles, force: true do |t|
|
|
311
|
-
t.integer :person_id
|
|
312
|
-
t.string :title
|
|
313
|
-
t.text :subject_header
|
|
314
|
-
t.text :body
|
|
315
|
-
t.string :type
|
|
316
|
-
t.boolean :published, default: true
|
|
317
|
-
end
|
|
318
|
-
|
|
319
|
-
create_table :comments, force: true do |t|
|
|
320
|
-
t.integer :article_id
|
|
321
|
-
t.integer :person_id
|
|
322
|
-
t.text :body
|
|
323
|
-
t.boolean :disabled, default: false
|
|
324
|
-
end
|
|
325
|
-
|
|
326
|
-
create_table :tags, force: true do |t|
|
|
327
|
-
t.string :name
|
|
328
|
-
end
|
|
329
|
-
|
|
330
|
-
create_table :articles_tags, force: true, id: false do |t|
|
|
331
|
-
t.integer :article_id
|
|
332
|
-
t.integer :tag_id
|
|
333
|
-
end
|
|
334
|
-
|
|
335
|
-
create_table :comments_tags, force: true, id: false do |t|
|
|
336
|
-
t.integer :comment_id
|
|
337
|
-
t.integer :tag_id
|
|
338
|
-
end
|
|
339
|
-
|
|
340
|
-
create_table :notes, force: true do |t|
|
|
341
|
-
t.integer :notable_id
|
|
342
|
-
t.string :notable_type
|
|
343
|
-
t.string :note
|
|
344
|
-
end
|
|
345
|
-
|
|
346
|
-
create_table :recommendations, force: true do |t|
|
|
347
|
-
t.integer :person_id
|
|
348
|
-
t.integer :target_person_id
|
|
349
|
-
t.integer :article_id
|
|
350
|
-
end
|
|
351
|
-
|
|
352
|
-
create_table :accounts, force: true do |t|
|
|
353
|
-
t.belongs_to :agent_account
|
|
354
|
-
t.belongs_to :trade_account
|
|
355
|
-
end
|
|
356
|
-
|
|
357
|
-
create_table :addresses, force: true do |t|
|
|
358
|
-
t.string :city
|
|
359
|
-
end
|
|
360
|
-
|
|
361
|
-
create_table :organizations, force: true do |t|
|
|
362
|
-
t.string :name
|
|
363
|
-
t.integer :address_id
|
|
364
|
-
end
|
|
365
|
-
|
|
366
|
-
create_table :employees, force: true do |t|
|
|
367
|
-
t.string :name
|
|
368
|
-
t.integer :organization_id
|
|
369
|
-
end
|
|
370
|
-
end
|
|
371
|
-
|
|
372
|
-
10.times do
|
|
373
|
-
person = FactoryBot.create(:person)
|
|
374
|
-
FactoryBot.create(:note, :for_person, notable: person)
|
|
375
|
-
3.times do
|
|
376
|
-
article = FactoryBot.create(:article, person: person)
|
|
377
|
-
3.times do
|
|
378
|
-
article.tags = [FactoryBot.create(:tag), FactoryBot.create(:tag), FactoryBot.create(:tag)]
|
|
379
|
-
end
|
|
380
|
-
FactoryBot.create(:note, :for_article, notable: article)
|
|
381
|
-
10.times do
|
|
382
|
-
FactoryBot.create(:comment, article: article, person: person)
|
|
383
|
-
end
|
|
384
|
-
end
|
|
385
|
-
end
|
|
386
|
-
|
|
387
|
-
FactoryBot.create(:comment,
|
|
388
|
-
body: 'First post!',
|
|
389
|
-
article: FactoryBot.create(:article, title: 'Hello, world!')
|
|
390
|
-
)
|
|
391
|
-
end
|
|
392
|
-
end
|
|
393
|
-
|
|
394
|
-
module SubDB
|
|
395
|
-
class Base < ApplicationRecord
|
|
396
|
-
self.abstract_class = true
|
|
397
|
-
establish_connection(
|
|
398
|
-
adapter: 'sqlite3',
|
|
399
|
-
database: ':memory:'
|
|
400
|
-
)
|
|
401
|
-
end
|
|
402
|
-
|
|
403
|
-
class OperationHistory < Base
|
|
404
|
-
end
|
|
405
|
-
|
|
406
|
-
module Schema
|
|
407
|
-
def self.create
|
|
408
|
-
s = ::ActiveRecord::Schema.new
|
|
409
|
-
s.instance_variable_set(:@connection, SubDB::Base.connection)
|
|
410
|
-
s.verbose = false
|
|
411
|
-
s.define({}) do
|
|
412
|
-
create_table :operation_histories, force: true do |t|
|
|
413
|
-
t.string :operation_type
|
|
414
|
-
t.integer :people_id
|
|
415
|
-
end
|
|
416
|
-
end
|
|
417
|
-
end
|
|
418
|
-
end
|
|
419
|
-
end
|