ordy 1.1.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 +7 -0
- data/.gitignore +1 -0
- data/.travis.yml +23 -0
- data/Appraisals +14 -0
- data/Dockerfile +18 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +89 -0
- data/LICENSE +21 -0
- data/Rakefile +8 -0
- data/VERSION +1 -0
- data/docker-compose.yml +6 -0
- data/gemfiles/rails_4.gemfile +8 -0
- data/gemfiles/rails_4.gemfile.lock +97 -0
- data/gemfiles/rails_5_0.gemfile +8 -0
- data/gemfiles/rails_5_0.gemfile.lock +91 -0
- data/gemfiles/rails_5_2.gemfile +8 -0
- data/gemfiles/rails_5_2.gemfile.lock +91 -0
- data/lib/config/settings.rb +9 -0
- data/lib/config/settings.yml +5 -0
- data/lib/ordy/helpers/action_view/orderable_link_helper.rb +61 -0
- data/lib/ordy/orm/active_record/orderable/by_association.rb +17 -0
- data/lib/ordy/orm/active_record/orderable/by_column.rb +17 -0
- data/lib/ordy/orm/active_record/orderable/by_specified.rb +23 -0
- data/lib/ordy/orm/active_record/orderable.rb +188 -0
- data/lib/ordy.rb +9 -0
- data/ordy.gemspec +32 -0
- data/readme.md +138 -0
- data/spec/ordy/orm/active_record/orderable_spec.rb +151 -0
- data/spec/spec_helper.rb +5 -0
- data/spec/support/orm/active_record/active_record_test_db.rb +95 -0
- metadata +172 -0
@@ -0,0 +1,188 @@
|
|
1
|
+
module Ordy
|
2
|
+
module Orm
|
3
|
+
module ActiveRecord
|
4
|
+
module Orderable
|
5
|
+
|
6
|
+
def self.included(base)
|
7
|
+
base.extend(Order::ClassMethods)
|
8
|
+
end
|
9
|
+
|
10
|
+
class Order
|
11
|
+
DELIMITER = '-'.freeze
|
12
|
+
include Enumerable
|
13
|
+
|
14
|
+
attr_reader :model, :default
|
15
|
+
|
16
|
+
# @param [ActiveRecord::Model] model
|
17
|
+
def initialize(model)
|
18
|
+
@model = model
|
19
|
+
@orderables = {}
|
20
|
+
end
|
21
|
+
|
22
|
+
def each(&block)
|
23
|
+
@orderables.each(&block)
|
24
|
+
end
|
25
|
+
|
26
|
+
def [](key)
|
27
|
+
@orderables.fetch(key)
|
28
|
+
end
|
29
|
+
|
30
|
+
# columns :name, :email
|
31
|
+
#
|
32
|
+
# @param [Array][Symbol] column_names
|
33
|
+
def columns(*column_names)
|
34
|
+
column_names.each do |column|
|
35
|
+
@orderables[column] = { args: { table: model.table_name, column: column },
|
36
|
+
orderable: Orderable::ByColumn }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# associations comment: :scripts
|
41
|
+
#
|
42
|
+
# @param [Array][Hash] associations
|
43
|
+
def associations(associations)
|
44
|
+
associations.each do |assoc, opts|
|
45
|
+
column, association = if opts.is_a?(Hash)
|
46
|
+
[opts.fetch(:column), opts.fetch(:as, assoc)]
|
47
|
+
else
|
48
|
+
[opts, assoc]
|
49
|
+
end
|
50
|
+
table_name = model.reflections.symbolize_keys.fetch(assoc).class_name.constantize.table_name
|
51
|
+
|
52
|
+
@orderables[association] = { args: { association: association,
|
53
|
+
table: table_name,
|
54
|
+
column: column },
|
55
|
+
orderable: Orderable::ByAssociation }
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# specified(state: %w(new pending_migration migrating failed))
|
60
|
+
#
|
61
|
+
# @param [Array][Hash] args
|
62
|
+
def specified(args)
|
63
|
+
args.each do |column, values|
|
64
|
+
specified_column = "specified_#{column}".to_sym
|
65
|
+
|
66
|
+
@orderables[specified_column] = { args: { table: model.table_name,
|
67
|
+
column: column,
|
68
|
+
values: values },
|
69
|
+
orderable: Orderable::BySpecified }
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# query :users do |scope, args|
|
74
|
+
# scope.where(...).order(field: args[:direction])
|
75
|
+
# end
|
76
|
+
#
|
77
|
+
# @param [Symbol] query
|
78
|
+
# @param [Proc] block
|
79
|
+
def query(query, &block)
|
80
|
+
@orderables[query] = { args: {}, orderable: block }
|
81
|
+
end
|
82
|
+
|
83
|
+
# default do
|
84
|
+
# order_by_specified(:state).order_by(started: :desc, created_at: :desc)
|
85
|
+
# end
|
86
|
+
#
|
87
|
+
# @param [Symbol] name
|
88
|
+
# @param [Proc] block
|
89
|
+
def default(name = nil, &block)
|
90
|
+
return -> { order_by(name => :asc) } if name.present?
|
91
|
+
@default = block if block_given?
|
92
|
+
@default ||= -> { order(nil) }
|
93
|
+
end
|
94
|
+
|
95
|
+
module ClassMethods
|
96
|
+
|
97
|
+
# orderable_by do
|
98
|
+
# column :name
|
99
|
+
# association :comments
|
100
|
+
# specified(state: %w(new pending_migration migrating failed))
|
101
|
+
#
|
102
|
+
# query(:topics) do |scope, args|
|
103
|
+
# ...
|
104
|
+
# end
|
105
|
+
# end
|
106
|
+
#
|
107
|
+
# @param [Proc] block
|
108
|
+
def orderable_by(&block)
|
109
|
+
@_orderables ||= Order.new(self)
|
110
|
+
@_orderables.instance_eval(&block)
|
111
|
+
@_orderables
|
112
|
+
end
|
113
|
+
|
114
|
+
# Model.order_by(name: :desc)
|
115
|
+
#
|
116
|
+
# Model.order_by('name-desc')
|
117
|
+
#
|
118
|
+
# Default direction :asc
|
119
|
+
# Model.order_by(name)
|
120
|
+
#
|
121
|
+
# Call default do method or order(nil)
|
122
|
+
# Model.order_by(nil)
|
123
|
+
# Model.order_by('')
|
124
|
+
#
|
125
|
+
# @param [Hash] order_query
|
126
|
+
def order_by(order_query = nil)
|
127
|
+
return default_order if order_query.nil? || order_query.blank?
|
128
|
+
return default_order(order_query) if order_query.is_a?(Symbol)
|
129
|
+
|
130
|
+
|
131
|
+
specs = case order_query
|
132
|
+
when String then parse_order_query(order_query)
|
133
|
+
when Hash then parse_order_hash(order_query)
|
134
|
+
else
|
135
|
+
[]
|
136
|
+
end
|
137
|
+
|
138
|
+
return default_order if specs.blank?
|
139
|
+
|
140
|
+
scope = default_scope
|
141
|
+
|
142
|
+
specs.each do |spec|
|
143
|
+
orderable = @_orderables[spec[:orderable]]
|
144
|
+
orderable[:args][:direction] = spec[:direction]
|
145
|
+
|
146
|
+
scope = orderable[:orderable].call(scope, orderable[:args])
|
147
|
+
end
|
148
|
+
|
149
|
+
scope
|
150
|
+
end
|
151
|
+
|
152
|
+
# Model.order_by_specified(:name)
|
153
|
+
#
|
154
|
+
# @param [Symbol] name
|
155
|
+
def order_by_specified(name)
|
156
|
+
orderable = @_orderables["specified_#{name}".to_sym]
|
157
|
+
orderable[:orderable].call(default_scope, orderable[:args])
|
158
|
+
end
|
159
|
+
|
160
|
+
def default_order(name = nil)
|
161
|
+
default_scope.instance_exec(&@_orderables.default(name))
|
162
|
+
end
|
163
|
+
|
164
|
+
private
|
165
|
+
|
166
|
+
# @param [Hash] order_query
|
167
|
+
# # @return [Array][Hash]
|
168
|
+
def parse_order_hash(order_query)
|
169
|
+
order_query.symbolize_keys.map { |(orderable, direction)| { orderable: orderable, direction: direction } }
|
170
|
+
end
|
171
|
+
|
172
|
+
# @param [String] order_query
|
173
|
+
# @return [Array][Hash]
|
174
|
+
def parse_order_query(order_query)
|
175
|
+
orderable, direction = order_query.to_s.split(DELIMITER).map(&:to_s).map(&:strip)
|
176
|
+
direction = 'asc' unless %w(desc asc).include?(direction)
|
177
|
+
[{ orderable: orderable.to_sym, direction: direction.to_sym }]
|
178
|
+
end
|
179
|
+
|
180
|
+
def default_scope
|
181
|
+
current_scope || where(nil)
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
data/lib/ordy.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
module Ordy
|
2
|
+
end
|
3
|
+
|
4
|
+
require_relative 'config/settings'
|
5
|
+
require_relative 'ordy/orm/active_record/orderable'
|
6
|
+
require_relative 'ordy/orm/active_record/orderable/by_association'
|
7
|
+
require_relative 'ordy/orm/active_record/orderable/by_column'
|
8
|
+
require_relative 'ordy/orm/active_record/orderable/by_specified'
|
9
|
+
require_relative 'ordy/helpers/action_view/orderable_link_helper'
|
data/ordy.gemspec
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
lib = File.expand_path('../lib', __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = 'ordy'
|
7
|
+
spec.version = File.read('VERSION')
|
8
|
+
spec.date = '2018-11-23'
|
9
|
+
spec.summary = 'Simple sorting gem'
|
10
|
+
spec.description = 'Simple sorting gem for RubyObject\'s and ORM\'s '
|
11
|
+
spec.authors = ['nine.ch Development-Team']
|
12
|
+
spec.email = 'development@nine.ch'
|
13
|
+
spec.files = ['lib/ordy.rb']
|
14
|
+
spec.homepage = 'http://github.com/ninech/'
|
15
|
+
spec.license = 'MIT'
|
16
|
+
|
17
|
+
spec.files = `git ls-files`.split("\n")
|
18
|
+
spec.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
spec.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
20
|
+
spec.require_paths = ['lib']
|
21
|
+
|
22
|
+
spec.required_ruby_version = '>= 2.0.0'
|
23
|
+
|
24
|
+
spec.add_development_dependency 'bundler'
|
25
|
+
spec.add_development_dependency 'rspec'
|
26
|
+
spec.add_development_dependency 'pry'
|
27
|
+
spec.add_development_dependency 'sqlite3'
|
28
|
+
spec.add_development_dependency 'appraisal'
|
29
|
+
|
30
|
+
spec.add_runtime_dependency 'activerecord', '>= 4.0.0'
|
31
|
+
spec.add_runtime_dependency 'actionview', '>= 4.0.0'
|
32
|
+
end
|
data/readme.md
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
[](https://travis-ci.org/ninech/ordy)
|
2
|
+
|
3
|
+
## Usage
|
4
|
+
|
5
|
+
#### Ordering
|
6
|
+
|
7
|
+
__Model usage__
|
8
|
+
|
9
|
+
```rb
|
10
|
+
class User < ApplicationRecord
|
11
|
+
include Ordy::Orm::ActiveRecord::Orderable
|
12
|
+
|
13
|
+
has_many :comments
|
14
|
+
|
15
|
+
orderable_by do
|
16
|
+
# order by field
|
17
|
+
columns :name, :email
|
18
|
+
|
19
|
+
# order by relations field
|
20
|
+
associations comments: :scripts
|
21
|
+
|
22
|
+
# sort by specified order
|
23
|
+
specified(state: %w(new, pending, active, removed))
|
24
|
+
|
25
|
+
# custom query
|
26
|
+
query :custom_query do |scope, args|
|
27
|
+
scope.where(name: 'example').order(email: args[:direction])
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
```
|
32
|
+
|
33
|
+
__Code usage__
|
34
|
+
|
35
|
+
```rb
|
36
|
+
# order by columns
|
37
|
+
User.order_by(name: :asc)
|
38
|
+
# or
|
39
|
+
User.order_by('name-asc')
|
40
|
+
|
41
|
+
# order by multiple columns
|
42
|
+
User.order_by(name: :asc, email: :desc)
|
43
|
+
# or
|
44
|
+
User.order_by(name: :asc).order_by(email: :desc)
|
45
|
+
|
46
|
+
# order by association column
|
47
|
+
User.order_by(comments: :asc)
|
48
|
+
|
49
|
+
# order by specified column values
|
50
|
+
User.order_by_specified(:state)
|
51
|
+
|
52
|
+
# order by custom query
|
53
|
+
User.order_by(custom_query: :asc)
|
54
|
+
|
55
|
+
# default ordering
|
56
|
+
User.order_by('')
|
57
|
+
# or
|
58
|
+
User.order_by(nil)
|
59
|
+
|
60
|
+
# ordering by more than one criteria
|
61
|
+
User.order_by(email: :asc, state: :desc)
|
62
|
+
```
|
63
|
+
|
64
|
+
#### View helper
|
65
|
+
|
66
|
+
__Helper inclusion__
|
67
|
+
|
68
|
+
```rb
|
69
|
+
# users_helper.rb
|
70
|
+
|
71
|
+
include Ordy::Helpers::ActionView::OrderableLinkHelper
|
72
|
+
```
|
73
|
+
|
74
|
+
__Html usage__
|
75
|
+
|
76
|
+
```html
|
77
|
+
# index.html
|
78
|
+
|
79
|
+
<%= order_link('link_title', 'ordering_filed') %>
|
80
|
+
```
|
81
|
+
|
82
|
+
__Controller usage__
|
83
|
+
|
84
|
+
```rb
|
85
|
+
class UsersController
|
86
|
+
def index
|
87
|
+
if params[:order_by].present? && params[:direction].present?
|
88
|
+
@users = User.order_by(params[:order_by] => params[:direction])
|
89
|
+
else
|
90
|
+
@users = User.all
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
```
|
95
|
+
|
96
|
+
## Run development environment
|
97
|
+
|
98
|
+
```bash
|
99
|
+
# position in gem dir
|
100
|
+
cd ordy
|
101
|
+
|
102
|
+
# build app
|
103
|
+
docker-compose build app
|
104
|
+
|
105
|
+
# run app and attach with bash
|
106
|
+
docker-compose run app /bin/bash
|
107
|
+
```
|
108
|
+
|
109
|
+
## Test
|
110
|
+
|
111
|
+
```bash
|
112
|
+
# install dependencies
|
113
|
+
bundle exec appraisal install
|
114
|
+
|
115
|
+
# run tests for rails 4 env
|
116
|
+
bundle exec appraisal rails-4 rspec
|
117
|
+
|
118
|
+
# run tests for rails 5 env
|
119
|
+
bundle exec appraisal rails-5 rspec
|
120
|
+
```
|
121
|
+
|
122
|
+
# Contributing
|
123
|
+
Bug reports and pull requests are very welcome [on GitHub](https://github.com/ninech/ordy).
|
124
|
+
|
125
|
+
Before opening a PR, please
|
126
|
+
|
127
|
+
extend the existing specs
|
128
|
+
- run rspec
|
129
|
+
- run rubocop and fix your warnings
|
130
|
+
- check if this README.md file needs adjustments
|
131
|
+
|
132
|
+
#License
|
133
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
134
|
+
|
135
|
+
# About
|
136
|
+
This gem is currently maintained and funded by [nine](https://www.nine.ch/de/home).
|
137
|
+
|
138
|
+
[](https://www.nine.ch)
|
@@ -0,0 +1,151 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require './spec/support/orm/active_record/active_record_test_db'
|
3
|
+
|
4
|
+
describe Ordy::Orm::ActiveRecord::Orderable do
|
5
|
+
|
6
|
+
describe '#order_by' do
|
7
|
+
|
8
|
+
context 'columns' do
|
9
|
+
let(:base_query) { User }
|
10
|
+
let(:order) { base_query.order_by(order_by) }
|
11
|
+
let(:result) { order.pluck(:name) }
|
12
|
+
|
13
|
+
context 'order by name: :asc' do
|
14
|
+
let(:order_by) { { name: :asc } }
|
15
|
+
specify { expect(result).to eq(%w(axample demo example)) }
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'order by name-asc' do
|
19
|
+
let(:order_by) { 'name-asc' }
|
20
|
+
specify { expect(result).to eq(%w(axample demo example)) }
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'order by name: :desc' do
|
24
|
+
let(:order_by) { { name: :desc } }
|
25
|
+
specify { expect(result).to eq(%w(example demo axample)) }
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'order by name-desc' do
|
29
|
+
let(:order_by) { 'name-desc' }
|
30
|
+
specify { expect(result).to eq(%w(example demo axample)) }
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'base query immutability' do
|
34
|
+
it 'should not change base query' do
|
35
|
+
query = base_query.where(name: 'example')
|
36
|
+
query.order_by(name: :desc).pluck(:name)
|
37
|
+
expect(query.to_sql).to eq('SELECT "users".* FROM "users" WHERE "users"."name" = \'example\'')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'associations' do
|
43
|
+
let(:base_query) { User }
|
44
|
+
let(:order) { base_query.order_by(order_by) }
|
45
|
+
let(:result) { order.pluck(:id) }
|
46
|
+
|
47
|
+
context 'order by name: :asc' do
|
48
|
+
let(:order_by) { { comments: :asc } }
|
49
|
+
specify { expect(result).to eq([3, 2, 1]) }
|
50
|
+
end
|
51
|
+
|
52
|
+
context 'order by name-asc' do
|
53
|
+
let(:order_by) { 'comments-asc' }
|
54
|
+
specify { expect(result).to eq([3, 2, 1]) }
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'order by name: :desc' do
|
58
|
+
let(:order_by) { { comments: :desc } }
|
59
|
+
specify { expect(result).to eq([1, 2, 3]) }
|
60
|
+
end
|
61
|
+
|
62
|
+
context 'order by name-desc' do
|
63
|
+
let(:order_by) { 'comments-desc' }
|
64
|
+
specify { expect(result).to eq([1, 2, 3]) }
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'base query immutability' do
|
68
|
+
it 'should not change base query' do
|
69
|
+
query = base_query.where(name: 'example')
|
70
|
+
query.order_by(comments: :desc).pluck(:id)
|
71
|
+
expect(query.to_sql).to eq('SELECT "users".* FROM "users" WHERE "users"."name" = \'example\'')
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context 'query' do
|
77
|
+
let(:base_query) { User }
|
78
|
+
let(:order) { base_query.order_by(order_by) }
|
79
|
+
let(:result) { order.pluck(:email) }
|
80
|
+
|
81
|
+
context 'order by name: :asc' do
|
82
|
+
let(:order_by) { { custom_query: :asc } }
|
83
|
+
specify { expect(result).to eq(%w(example@example.com custom_example@example.com)) }
|
84
|
+
end
|
85
|
+
|
86
|
+
context 'order by name-asc' do
|
87
|
+
let(:order_by) { 'custom_query-asc' }
|
88
|
+
specify { expect(result).to eq(%w(example@example.com custom_example@example.com)) }
|
89
|
+
end
|
90
|
+
|
91
|
+
context 'order by name: :desc' do
|
92
|
+
let(:order_by) { { custom_query: :desc } }
|
93
|
+
specify { expect(result).to eq(%w(custom_example@example.com example@example.com)) }
|
94
|
+
end
|
95
|
+
|
96
|
+
context 'order by name-desc' do
|
97
|
+
let(:order_by) { 'custom_query-desc' }
|
98
|
+
specify { expect(result).to eq(%w(custom_example@example.com example@example.com)) }
|
99
|
+
end
|
100
|
+
|
101
|
+
context 'base query immutability' do
|
102
|
+
it 'should not change base query' do
|
103
|
+
query = base_query.where(name: 'example')
|
104
|
+
query.order_by('custom_query-desc').pluck(:email)
|
105
|
+
expect(query.to_sql).to eq('SELECT "users".* FROM "users" WHERE "users"."name" = \'example\'')
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context 'default ordering' do
|
111
|
+
let(:spacing) { ENV['BUNDLE_GEMFILE'].include?('gemfiles/rails_4.gemfile') ? ' ' : ' ' }
|
112
|
+
|
113
|
+
context 'default proc' do
|
114
|
+
let(:query) { User.where(name: 'example') }
|
115
|
+
|
116
|
+
it 'should return asc ordering for nil' do
|
117
|
+
expect(query.order_by(nil).to_sql).to eq('SELECT "users".* FROM "users" WHERE "users"."name" = \'example\'' + spacing + 'ORDER BY "users"."state"=\'active\' DESC,"users"."state"=\'pending\' DESC, users.name asc')
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'should not mutate base query' do
|
121
|
+
expect(query.to_sql).to eq('SELECT "users".* FROM "users" WHERE "users"."name" = \'example\'')
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
context 'default field direction' do
|
126
|
+
let(:query) { User.where(name: 'example') }
|
127
|
+
|
128
|
+
it 'should return asc ordering for :field' do
|
129
|
+
expect(query.order_by(:name).to_sql).to eq('SELECT "users".* FROM "users" WHERE "users"."name" = \'example\'' + spacing + 'ORDER BY users.name asc')
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'should not mutate base query' do
|
133
|
+
expect(query.to_sql).to eq('SELECT "users".* FROM "users" WHERE "users"."name" = \'example\'')
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
context 'default ordering' do
|
138
|
+
let(:base_query_sql) { 'SELECT "comments".* FROM "comments" WHERE "comments"."user_id" = 1' }
|
139
|
+
let(:query) { Comment.where(user_id: 1) }
|
140
|
+
|
141
|
+
it 'should return asc ordering for \'\'' do
|
142
|
+
expect(query.order_by('').to_sql).to eq(base_query_sql)
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'should not mutate base query' do
|
146
|
+
expect(query.to_sql).to eq(base_query_sql)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
|
3
|
+
RSpec.configure do |config|
|
4
|
+
config.before(:all) do
|
5
|
+
create_db
|
6
|
+
migrate
|
7
|
+
seed
|
8
|
+
end
|
9
|
+
|
10
|
+
config.after(:all) do
|
11
|
+
drop_db
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def create_db
|
16
|
+
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')
|
17
|
+
end
|
18
|
+
|
19
|
+
def migrate
|
20
|
+
ActiveRecord::Base.connection.create_table :users do |t|
|
21
|
+
t.text :name
|
22
|
+
t.text :email
|
23
|
+
t.text :state
|
24
|
+
end
|
25
|
+
|
26
|
+
ActiveRecord::Base.connection.create_table :comments do |t|
|
27
|
+
t.integer :user_id
|
28
|
+
t.text :content
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def seeds
|
33
|
+
[
|
34
|
+
{ table: "'users'",
|
35
|
+
fields: %w(id name email state),
|
36
|
+
values: [
|
37
|
+
[1, "'demo'", "'demo@demo.com'", "'active'"],
|
38
|
+
[2, "'axample'", "'example@example.com'", "'pending'"],
|
39
|
+
[3, "'example'", "'custom_example@example.com'", "'active'"]
|
40
|
+
]
|
41
|
+
},
|
42
|
+
{ table: "'comments'",
|
43
|
+
fields: %w(content user_id),
|
44
|
+
values: [
|
45
|
+
["'example'", 1],
|
46
|
+
["'demo'", 2]
|
47
|
+
]
|
48
|
+
}
|
49
|
+
]
|
50
|
+
end
|
51
|
+
|
52
|
+
def seed
|
53
|
+
seeds.each do |model|
|
54
|
+
model[:values].each do |args|
|
55
|
+
ActiveRecord::Base.connection.execute("INSERT INTO #{model[:table]} (#{model[:fields].join(',')}) VALUES (#{args.join(',')})")
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def drop_db
|
61
|
+
[:users, :comments].each do |table|
|
62
|
+
ActiveRecord::Base.connection.drop_table table
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class Comment < ActiveRecord::Base
|
67
|
+
include Ordy::Orm::ActiveRecord::Orderable
|
68
|
+
|
69
|
+
orderable_by do
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
belongs_to :user
|
74
|
+
end
|
75
|
+
|
76
|
+
class User < ActiveRecord::Base
|
77
|
+
include Ordy::Orm::ActiveRecord::Orderable
|
78
|
+
|
79
|
+
has_many :comments
|
80
|
+
|
81
|
+
orderable_by do
|
82
|
+
columns :name, :email
|
83
|
+
associations comments: :content
|
84
|
+
specified(state: %w(active pending))
|
85
|
+
|
86
|
+
query :custom_query do |scope, args|
|
87
|
+
scope.where('email LIKE \'%example%\'',).order(id: args.fetch(:direction))
|
88
|
+
end
|
89
|
+
|
90
|
+
default do
|
91
|
+
order_by_specified(:state).order_by(:name)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|