data_tables-responder 0.2.3 → 0.3.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
  SHA1:
3
- metadata.gz: 843cafe60eba33bd11e4a1db95f408e29dc95df6
4
- data.tar.gz: 9e52d51f84b77cea416333e8634198019c497d7c
3
+ metadata.gz: c9e0c1d6257f60b5b07b2e17d6dcbc1ca2fdc39c
4
+ data.tar.gz: 0b559fd04b9cc9fce90cf40fda777e63f6c942bc
5
5
  SHA512:
6
- metadata.gz: 702847fb2fee755b7a439c959d247f7829f1bc70ba2eb24cebcca9cdccd7d6c41673b31f7edb5be44a1e53f352d133e37681ef056e71b5b8a2bf2eb9f8fb15d2
7
- data.tar.gz: 007d3b0842e8fb4ce9efbd38edb81a4b96761667409bce1c7c2d5a82cc8f1204b190f45ce4c2decd9e88e4f61fe46532516aa1346fb7a0e26ad435eabf35fc04
6
+ metadata.gz: 7eb090ae3ef6f7968594f31b28161cbd5e527078ed53da634358eb20b1a5a9e3434a4cbe69b53bf9193a2a227bb7045f350f23b2183d717249e96dc67fbfe68c
7
+ data.tar.gz: 81ab0c4502f9b29b793b5ab514056622580862fe036483d8b65773734c9eff9c61e79ce5a87e4e5e93529c7273d2b2805441fb0124f1a263aae2ea48565cba14
@@ -26,7 +26,7 @@ Gem::Specification.new do |spec|
26
26
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
27
27
  spec.require_paths = ['lib']
28
28
 
29
- spec.add_dependency 'active_model_serializers', '~> 0.10.0'
29
+ spec.add_dependency 'active_model_serializers', '~> 0.10.4'
30
30
  spec.add_dependency 'count_estimate'
31
31
 
32
32
  spec.add_development_dependency 'bundler', '~> 1.12'
@@ -0,0 +1,28 @@
1
+ module ActiveModelSerializers
2
+ module Adapter
3
+ class DataTables
4
+
5
+ class Meta
6
+ def initialize(serializer)
7
+ @object = serializer.object
8
+ @scope = serializer.scope
9
+
10
+ # Use the return value of the block unless it is nil.
11
+ if serializer._meta.respond_to?(:call)
12
+ @value = instance_eval(&serializer._meta)
13
+ else
14
+ @value = serializer._meta
15
+ end
16
+ end
17
+
18
+ def as_json
19
+ @value
20
+ end
21
+
22
+ protected
23
+
24
+ attr_reader :object, :scope
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,22 @@
1
+ module DataTables
2
+ module ActiveModelSerializers
3
+ class Adapter
4
+ class Pagination
5
+
6
+ attr_reader :collection
7
+
8
+ def initialize(serializer)
9
+ @collection = serializer.object
10
+ end
11
+
12
+ def as_h
13
+ {
14
+ recordsTotal: collection&.total_entries&.to_i,
15
+ recordsFiltered: @collection&.unscope(:limit, :offset)&.count_estimate&.to_i
16
+ }
17
+ end
18
+
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,43 @@
1
+ require 'active_model_serializers'
2
+
3
+ module DataTables
4
+ module ActiveModelSerializers
5
+ class Adapter < ::ActiveModelSerializers::Adapter::Json
6
+ extend ActiveSupport::Autoload
7
+ autoload :Pagination
8
+ autoload :Meta
9
+
10
+ def serializable_hash(options = nil)
11
+ options = serialization_options(options)
12
+
13
+ serialized_hash = {
14
+ data: ::ActiveModelSerializers::Adapter::Attributes.new(serializer, instance_options).serializable_hash(options)
15
+ }
16
+ serialized_hash[meta_key] = meta unless meta.blank?
17
+ serialized_hash.merge!(pagination) unless pagination.blank?
18
+
19
+ self.class.transform_key_casing!(serialized_hash, instance_options)
20
+ end
21
+
22
+ def meta_key
23
+ instance_options.fetch(:meta_key, 'meta'.freeze)
24
+ end
25
+
26
+ protected
27
+
28
+ def pagination
29
+ Pagination.new(serializer).as_h
30
+ end
31
+
32
+ def meta
33
+ {
34
+ sql: serializer.object.to_sql
35
+ }.merge(instance_options.fetch(:meta, {}))
36
+ # }.merge(Meta.new(@serializer))
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ # Register adapter manually (due to namespacing)
43
+ ActiveModelSerializers::Adapter.register(:dt, DataTables::ActiveModelSerializers::Adapter)
@@ -0,0 +1,56 @@
1
+ # In controllers, use `render dt: model` rather than `render json: model, adapter: :dt`.
2
+ #
3
+ # For example, in a controller action, we can:
4
+ # respond_to do |format|
5
+ # format.dt { render dt: model }
6
+ # end
7
+ #
8
+ # or
9
+ #
10
+ # render dt: model
11
+ #
12
+ # No wrapper format needed as it does not apply (i.e. no `wrap_parameters format: [dt]`)
13
+ module DataTables
14
+ module ActiveModelSerializers
15
+ MEDIA_TYPE = 'application/json'.freeze
16
+ HEADERS = {
17
+ response: { 'CONTENT_TYPE'.freeze => MEDIA_TYPE },
18
+ request: { 'ACCEPT'.freeze => MEDIA_TYPE }
19
+ }.freeze
20
+
21
+ def self.install
22
+ # actionpack/lib/action_dispatch/http/mime_types.rb
23
+ Mime::Type.register_alias MEDIA_TYPE, :dt, %w( text/plain text/x-json application/jsonrequest application/dt application/datatable )
24
+
25
+ # if Rails::VERSION::MAJOR >= 5
26
+ # ActionDispatch::Request.parameter_parsers[:dt] = parser
27
+ # else
28
+ # ActionDispatch::ParamsParser::DEFAULT_PARSERS[Mime[:dt]] = parser
29
+ # end
30
+
31
+ ::ActionController::Renderers.add :dt do |json, options|
32
+ json = serialize_dt(json, options).to_json(options) unless json.is_a?(String)
33
+ self.content_type ||= Mime[:dt]
34
+ self.response_body = json
35
+ end
36
+ end
37
+
38
+ module ControllerSupport
39
+ def serialize_dt(resource, options)
40
+ options[:adapter] = :dt
41
+ options.fetch(:serialization_context) do
42
+ options[:serialization_context] = ::ActiveModelSerializers::SerializationContext.new(request)
43
+ end
44
+ # Magic happens here
45
+ resource = DataTables::Responder.respond(resource, request.params)
46
+ get_serializer(resource, options)
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ DataTables::ActiveModelSerializers.install
53
+
54
+ ActiveSupport.on_load(:action_controller) do
55
+ include DataTables::ActiveModelSerializers::ControllerSupport
56
+ end
@@ -1,26 +1,20 @@
1
+ require 'count_estimate'
2
+
1
3
  module DataTables
2
4
  module Modules
3
5
  class Pagination
4
- MissingSerializationContextError = Class.new(KeyError)
5
6
  FIRST_PAGE = 1
6
7
 
7
8
  attr_reader :collection, :context
8
9
 
9
- def initialize(collection, adapter_options)
10
+ def initialize(collection, request_parameters)
10
11
  @collection = collection
11
- @adapter_options = adapter_options
12
- @context = adapter_options.fetch(:serialization_context) do
13
- fail MissingSerializationContextError, <<-EOF.freeze
14
- Datatables::Pagination requires a ActiveModelSerializers::SerializationContext.
15
- Please pass a ':serialization_context' option or
16
- override CollectionSerializer#paginated? to return 'false'.
17
- EOF
18
- end
12
+ @request_parameters = request_parameters
19
13
  end
20
14
 
21
15
  def paginate
22
- start = (request_parameters[:start] || '0').to_i
23
- length = (request_parameters[:length] || '10').to_i
16
+ start = (@request_parameters[:start] || '0').to_i
17
+ length = (@request_parameters[:length] || '10').to_i
24
18
  page = (start / length) + 1
25
19
  @collection = @collection.paginate(page: page, per_page: length, total_entries: records_total)
26
20
  end
@@ -46,9 +40,6 @@ module DataTables
46
40
 
47
41
  private
48
42
 
49
- def request_parameters
50
- @request_parameters ||= context.request_parameters
51
- end
52
43
  end
53
44
  end
54
45
  end
@@ -1,30 +1,22 @@
1
1
  module DataTables
2
2
  module Modules
3
3
  class Search
4
- MissingSerializationContextError = Class.new(KeyError)
5
4
 
6
5
  attr_reader :collection, :context
7
6
 
8
- def initialize(collection, adapter_options)
7
+ def initialize(collection, request_parameters)
9
8
  @collection = collection
10
- @adapter_options = adapter_options
11
- @context = adapter_options.fetch(:serialization_context) do
12
- fail MissingSerializationContextError, <<-EOF.freeze
13
- Datatables::Search requires a ActiveModelSerializers::SerializationContext.
14
- Please pass a ':serialization_context' option or
15
- override CollectionSerializer#searchable? to return 'false'.
16
- EOF
17
- end
9
+ @request_parameters = request_parameters
18
10
  end
19
11
 
20
12
  def search
21
- default_search = request_parameters.dig(:search, :value)
13
+ default_search = @request_parameters.dig(:search, :value)
22
14
 
23
15
  model = @collection.try(:model) || @collection
24
16
  arel_table = model.arel_table
25
17
  columns = searchable_columns(default_search)
26
18
 
27
- searches = DataTables.flat_keys_to_nested columns
19
+ searches = DataTables::Responder.flat_keys_to_nested columns
28
20
 
29
21
  search_by = build_search(model, searches)
30
22
 
@@ -42,11 +34,11 @@ module DataTables
42
34
  assoc = model.reflect_on_association(column)
43
35
  assoc_klass = assoc.klass
44
36
 
45
- outer_join = join_type.new(assoc_klass.arel_table,
37
+ join = join_type.new(assoc_klass.arel_table,
46
38
  Arel::Nodes::On.new(
47
39
  model.arel_table[assoc.foreign_key].eq(assoc_klass.arel_table[assoc.active_record_primary_key])
48
40
  ))
49
- @collection = @collection.joins(outer_join)
41
+ @collection = @collection.joins(join)
50
42
  queries << build_search(assoc_klass, query).reduce(:and)
51
43
  else
52
44
  col_s = column.to_s
@@ -73,7 +65,7 @@ module DataTables
73
65
 
74
66
  def searchable_columns(default_search)
75
67
  @searchable_columns = {}
76
- request_parameters[:columns]&.inject(@searchable_columns) do |a, b|
68
+ @request_parameters[:columns]&.inject(@searchable_columns) do |a, b|
77
69
  if (b[:searchable] && b[:data].present?)
78
70
  if ((value = b.dig(:search, :value).present? ? b.dig(:search, :value) : default_search).present?)
79
71
  a[b[:data]] = value
@@ -87,10 +79,6 @@ module DataTables
87
79
 
88
80
  private
89
81
 
90
- def request_parameters
91
- @request_parameters ||= context.request_parameters
92
- end
93
-
94
82
  end
95
83
  end
96
84
  end
@@ -1,11 +1,17 @@
1
- require 'rails'
1
+ require 'rails/railtie'
2
+ require 'action_controller'
3
+ require 'action_controller/railtie'
2
4
 
3
5
  module DataTables
4
6
  module Responder
5
7
  class Railtie < ::Rails::Railtie
6
- initializer "data_tables.configure", after: 'active_model_serializers.prepare_serialization_context' do
7
- Mime::Type.register_alias 'application/json', :dt, %w( text/plain text/x-json application/jsonrequest application/dt application/datatable )
8
+
9
+ initializer 'data_tables-responder.action_controller', after: 'active_model_serializers.action_controller' do
10
+ ActiveSupport.on_load(:action_controller) do
11
+ require 'data_tables/active_model_serializers/register_dt_renderer'
12
+ end
8
13
  end
14
+
9
15
  end
10
16
  end
11
17
  end
@@ -1,5 +1,5 @@
1
1
  module DataTables
2
2
  module Responder
3
- VERSION = '0.2.3'
3
+ VERSION = '0.3.0'
4
4
  end
5
5
  end
@@ -0,0 +1,68 @@
1
+ require "data_tables/responder/version"
2
+
3
+ require 'data_tables/modules/pagination'
4
+ require 'data_tables/modules/search'
5
+
6
+ require 'data_tables/active_model_serializers/adapter'
7
+ require 'data_tables/responder/railtie' if defined? ::Rails::Railtie
8
+
9
+ module DataTables
10
+ module Responder
11
+
12
+ def self.respond(resource, params)
13
+ model = resource.try(:model) || resource
14
+
15
+ results = resource
16
+ hashed_orders = transmute_datatable_order(params[:order], params[:columns])
17
+ orders = flat_keys_to_nested hashed_orders
18
+
19
+ order_by = orders.collect do |k, order|
20
+ if order.is_a? Hash
21
+ if (klass = model.reflect_on_association(k).try(:klass))
22
+ results = results.joins(k)
23
+ klass.arel_table[order.first.first].send(order.first.last)
24
+ end
25
+ else
26
+ { k => order }
27
+ end
28
+ end
29
+
30
+ results = search(results, params)
31
+
32
+ # Rails.logger.warn "SEARCH BY: #{search_by}"
33
+ results = order_by.inject(results) { |r, o| r.order(o) }
34
+ results = paginate(results, params)
35
+ end
36
+
37
+ def self.flat_keys_to_nested(hash)
38
+ hash.each_with_object({}) do |(key, value), all|
39
+ key_parts = key.split('.').map!(&:to_sym)
40
+ leaf = key_parts[0...-1].inject(all) { |h, k| h[k] ||= {} }
41
+ leaf[key_parts.last] = value
42
+ end
43
+ end
44
+
45
+
46
+ def self.paginate(collection, params)
47
+ Modules::Pagination.new(collection, params).paginate
48
+ end
49
+
50
+ def self.search(collection, params)
51
+ Modules::Search.new(collection, params).search
52
+ end
53
+
54
+ def self.transmute_datatable_order(orders, columns)
55
+ Hash[if orders.is_a? Array
56
+ orders.collect do |order|
57
+ if (name = columns[order[:column]][:data]).present?
58
+ [name, order[:dir]]
59
+ else
60
+ nil
61
+ end
62
+ end
63
+ else
64
+ []
65
+ end.compact]
66
+ end
67
+ end
68
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: data_tables-responder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dale Stevens
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-01-11 00:00:00.000000000 Z
11
+ date: 2017-01-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: active_model_serializers
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.10.0
19
+ version: 0.10.4
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.10.0
26
+ version: 0.10.4
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: count_estimate
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -96,11 +96,13 @@ files:
96
96
  - bin/console
97
97
  - bin/setup
98
98
  - data_tables-responder.gemspec
99
- - lib/data_tables-responder.rb
100
- - lib/data_tables/adapter.rb
99
+ - lib/data_tables/active_model_serializers/adapter.rb
100
+ - lib/data_tables/active_model_serializers/adapter/meta.rb
101
+ - lib/data_tables/active_model_serializers/adapter/pagination.rb
102
+ - lib/data_tables/active_model_serializers/register_dt_renderer.rb
101
103
  - lib/data_tables/modules/pagination.rb
102
104
  - lib/data_tables/modules/search.rb
103
- - lib/data_tables/monkey_patch/active_model_serializers/serialization_context.rb
105
+ - lib/data_tables/responder.rb
104
106
  - lib/data_tables/responder/railtie.rb
105
107
  - lib/data_tables/responder/version.rb
106
108
  homepage: https://github.com/TwilightCoders/data_tables-responder
@@ -1,100 +0,0 @@
1
- require 'active_model_serializers'
2
- require 'count_estimate'
3
- require 'data_tables/modules/pagination'
4
- require 'data_tables/modules/search'
5
-
6
- module DataTables
7
- def self.flat_keys_to_nested(hash)
8
- hash.each_with_object({}) do |(key, value), all|
9
- key_parts = key.split('.').map!(&:to_sym)
10
- leaf = key_parts[0...-1].inject(all) { |h, k| h[k] ||= {} }
11
- leaf[key_parts.last] = value
12
- end
13
- end
14
-
15
- class Adapter < ::ActiveModelSerializers::Adapter::Base
16
-
17
- def serializable_hash(options)
18
- options = serialization_options(options)
19
- @serialization_context = options[:serialization_context]
20
-
21
- collection = serializer.object
22
-
23
- params = @serialization_context.request_parameters
24
- model = collection.try(:model) || collection
25
-
26
- @results = collection
27
- hashed_orders = transmute_datatable_order(params[:order], params[:columns])
28
- orders = DataTables.flat_keys_to_nested hashed_orders
29
-
30
- order_by = orders.collect do |k, order|
31
- if order.is_a? Hash
32
- if (klass = model.reflect_on_association(k).try(:klass))
33
- @results = @results.joins(k)
34
- klass.arel_table[order.first.first].send(order.first.last)
35
- end
36
- else
37
- { k => order }
38
- end
39
- end
40
-
41
- @results = search(@results)
42
-
43
- # Rails.logger.warn "SEARCH BY: #{search_by}"
44
- @results = order_by.inject(@results) { |r, o| r.order(o) }
45
- @results = paginate(@results)
46
-
47
- new_serializer = serializer.class.new(@results, serializer.instance_variable_get(:@options))
48
- serialized_hash = {
49
- data: ::ActiveModelSerializers::Adapter::Attributes.new(new_serializer, instance_options).serializable_hash(options)
50
- }
51
- serialized_hash[meta_key] = meta unless meta.blank?
52
- serialized_hash.merge!(@pagination.as_json) unless @pagination.blank?
53
-
54
- self.class.transform_key_casing!(serialized_hash, instance_options)
55
- # binding.pry
56
- end
57
-
58
- def reformatted_columns(params)
59
- # binding.pry
60
- params[:columns]
61
- end
62
-
63
- protected
64
-
65
- def paginate(collection)
66
- @pagination ||= Modules::Pagination.new(collection, instance_options)
67
- collection = @pagination.paginate
68
- end
69
-
70
- def search(collection)
71
- @search ||= Modules::Search.new(collection, instance_options)
72
- collection = @search.search
73
- end
74
-
75
- def transmute_datatable_order(orders, columns)
76
- Hash[if orders.is_a? Array
77
- orders.collect do |order|
78
- if (name = columns[order[:column]][:data]).present?
79
- [name, order[:dir]]
80
- else
81
- nil
82
- end
83
- end
84
- else
85
- []
86
- end.compact]
87
- end
88
-
89
- def meta
90
- {
91
- sql: @results.to_sql
92
- }.merge(instance_options.fetch(:meta, {}))
93
- end
94
-
95
- def meta_key
96
- instance_options.fetch(:meta_key, 'meta'.freeze)
97
- end
98
-
99
- end
100
- end
@@ -1,21 +0,0 @@
1
- require 'active_model_serializers/serialization_context'
2
- module ActiveModelSerializers
3
- class SerializationContext
4
- attr_reader :request_parameters
5
-
6
- def initialize(*args)
7
- options = args.extract_options!
8
- if args.size == 1
9
- request = args.pop
10
- options[:request_url] = request.original_url[/\A[^?]+/]
11
- options[:query_parameters] = request.query_parameters
12
- options[:request_parameters] = request.request_parameters
13
- end
14
- @request_url = options.delete(:request_url)
15
- @query_parameters = options.delete(:query_parameters)
16
- @request_parameters = options.delete(:request_parameters)
17
- @url_helpers = options.delete(:url_helpers) || self.class.url_helpers
18
- @default_url_options = options.delete(:default_url_options) || self.class.default_url_options
19
- end
20
- end
21
- end
@@ -1,11 +0,0 @@
1
- require "data_tables/responder/version"
2
- # Monkey-patch :/
3
- require "data_tables/monkey_patch/active_model_serializers/serialization_context"
4
-
5
- require 'data_tables/adapter'
6
- require 'data_tables/responder/railtie' if defined? ::Rails::Railtie
7
-
8
- module DataTables
9
- module Responder
10
- end
11
- end