netzke-basepack 0.7.4 → 0.7.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. data/.travis.yml +11 -0
  2. data/CHANGELOG.rdoc +10 -0
  3. data/README.md +36 -2
  4. data/Rakefile +1 -3
  5. data/config/ci/before-travis.sh +28 -0
  6. data/lib/netzke/active_record.rb +10 -8
  7. data/lib/netzke/active_record/attributes.rb +28 -17
  8. data/lib/netzke/active_record/relation_extensions.rb +3 -1
  9. data/lib/netzke/basepack.rb +10 -2
  10. data/lib/netzke/basepack/action_column.rb +6 -8
  11. data/lib/netzke/basepack/data_accessor.rb +11 -174
  12. data/lib/netzke/basepack/data_adapters/abstract_adapter.rb +164 -0
  13. data/lib/netzke/basepack/data_adapters/active_record_adapter.rb +279 -0
  14. data/lib/netzke/basepack/data_adapters/data_mapper_adapter.rb +264 -0
  15. data/lib/netzke/basepack/data_adapters/sequel_adapter.rb +260 -0
  16. data/lib/netzke/basepack/form_panel.rb +3 -3
  17. data/lib/netzke/basepack/form_panel/fields.rb +6 -10
  18. data/lib/netzke/basepack/form_panel/javascripts/form_panel.js +1 -0
  19. data/lib/netzke/basepack/form_panel/services.rb +15 -16
  20. data/lib/netzke/basepack/grid_panel.rb +16 -10
  21. data/lib/netzke/basepack/grid_panel/columns.rb +6 -7
  22. data/lib/netzke/basepack/grid_panel/javascripts/event_handling.js +29 -27
  23. data/lib/netzke/basepack/grid_panel/services.rb +13 -90
  24. data/lib/netzke/basepack/paging_form_panel.rb +3 -3
  25. data/lib/netzke/basepack/query_builder.rb +2 -0
  26. data/lib/netzke/basepack/query_builder/javascripts/query_builder.js +29 -19
  27. data/lib/netzke/basepack/search_panel.rb +6 -3
  28. data/lib/netzke/basepack/search_panel/javascripts/search_panel.js +2 -1
  29. data/lib/netzke/basepack/search_window.rb +2 -1
  30. data/lib/netzke/basepack/version.rb +1 -1
  31. data/lib/netzke/data_mapper.rb +18 -0
  32. data/lib/netzke/data_mapper/attributes.rb +273 -0
  33. data/lib/netzke/data_mapper/combobox_options.rb +11 -0
  34. data/lib/netzke/data_mapper/relation_extensions.rb +38 -0
  35. data/lib/netzke/sequel.rb +18 -0
  36. data/lib/netzke/sequel/attributes.rb +274 -0
  37. data/lib/netzke/sequel/combobox_options.rb +10 -0
  38. data/lib/netzke/sequel/relation_extensions.rb +40 -0
  39. data/netzke-basepack.gemspec +24 -13
  40. data/test/basepack_test_app/Gemfile +33 -8
  41. data/test/basepack_test_app/Gemfile.lock +98 -79
  42. data/test/basepack_test_app/Guardfile +46 -0
  43. data/test/basepack_test_app/app/components/book_grid_with_persistence.rb +3 -0
  44. data/test/basepack_test_app/app/components/extras/book_presentation.rb +10 -3
  45. data/test/basepack_test_app/app/models/address.rb +27 -1
  46. data/test/basepack_test_app/app/models/author.rb +28 -0
  47. data/test/basepack_test_app/app/models/book.rb +43 -0
  48. data/test/basepack_test_app/app/models/book_with_custom_primary_key.rb +22 -0
  49. data/test/basepack_test_app/app/models/role.rb +21 -0
  50. data/test/basepack_test_app/app/models/user.rb +24 -0
  51. data/test/basepack_test_app/config/database.yml.sample +11 -10
  52. data/test/basepack_test_app/config/database.yml.travis +15 -0
  53. data/test/basepack_test_app/config/initializers/data_mapper_logging.rb +3 -0
  54. data/test/basepack_test_app/config/initializers/sequel.rb +26 -0
  55. data/test/basepack_test_app/db/schema.rb +0 -3
  56. data/test/basepack_test_app/features/grid_panel.feature +28 -8
  57. data/test/basepack_test_app/features/grid_sorting.feature +6 -6
  58. data/test/basepack_test_app/features/paging_form_panel.feature +13 -13
  59. data/test/basepack_test_app/features/search_in_grid.feature +31 -31
  60. data/test/basepack_test_app/features/step_definitions/generic_steps.rb +3 -1
  61. data/test/basepack_test_app/features/support/env.rb +17 -4
  62. data/test/basepack_test_app/lib/tasks/travis.rake +7 -0
  63. data/test/basepack_test_app/spec/components/form_panel_spec.rb +2 -2
  64. data/test/basepack_test_app/spec/data_adapter/adapter_spec.rb +68 -0
  65. data/test/basepack_test_app/spec/{active_record → data_adapter}/attributes_spec.rb +12 -4
  66. data/test/basepack_test_app/spec/data_adapter/relation_extensions_spec.rb +125 -0
  67. data/test/basepack_test_app/spec/spec_helper.rb +9 -0
  68. data/test/unit/active_record_basepack_test.rb +1 -1
  69. data/test/unit/grid_panel_test.rb +1 -1
  70. metadata +26 -31
  71. data/app/models/netzke_field_list.rb +0 -261
  72. data/app/models/netzke_model_attr_list.rb +0 -21
  73. data/app/models/netzke_persistent_array_auto_model.rb +0 -57
  74. data/test/basepack_test_app/spec/active_record/relation_extensions_spec.rb +0 -44
data/.travis.yml ADDED
@@ -0,0 +1,11 @@
1
+ rvm:
2
+ - 1.9.2
3
+
4
+ env:
5
+ - ORM=ar
6
+ - ORM=dm
7
+ - ORM=sq
8
+
9
+ bundler_args: "--without development production profiling"
10
+ before_script: "./config/ci/before-travis.sh"
11
+ script: "cd test/basepack_test_app ; bundle exec rake travis"
data/CHANGELOG.rdoc CHANGED
@@ -1,3 +1,13 @@
1
+ = 0.7.5 - ?
2
+ * improvements
3
+ * data-related operations in grids and forms are moved to data adapters; implemented (partial) support for DataMapper and Sequel (see updated README)
4
+ * afterApply event in forms and grids (pschyska)
5
+ * apply event fired before apply button is processed in FormPanel (pschyska)
6
+
7
+ * bug fix
8
+ * advanced search panel works again (pididi)
9
+ * fixed a problem with session and GridPanel
10
+
1
11
  = 0.7.4 - 2012-03-05
2
12
  * bug fix
3
13
  * :enable_pagination is now respected in GridPanel
data/README.md CHANGED
@@ -5,7 +5,7 @@ A pack of pre-built [Netzke](http://netzke.org) components - such as grid, form,
5
5
  ## Requirements
6
6
 
7
7
  * Ruby 1.9.2 (1.8.7 may work, too)
8
- * Rails >= 3.0.0
8
+ * Rails ~> 3.1.0
9
9
  * Ext JS = 4.0.2a
10
10
 
11
11
  ## Installation
@@ -36,6 +36,40 @@ After starting up the test app, you can see the list of functional test componen
36
36
 
37
37
  http://localhost:3000/
38
38
 
39
+ ## Note on testing with DataMapper/Sequel Support
40
+ To install the test app with DataMapper or Sequel, put ORM=dm or ORM=sq
41
+ into your environment.
42
+ For example to set-up DataMapper support run
43
+
44
+ # in test/basepack_test_app
45
+ ORM=dm bundle install
46
+
47
+ To run the test app in DataMapper-Mode (will use DataMapper models instead of ActiveRecord models)
48
+
49
+ # in test/basepack_test_app
50
+ ORM=dm rails s
51
+
52
+ To run the test suite
53
+
54
+ # in test/basepack_test_app
55
+ ORM=dm bundle exec rake
56
+
57
+ etc.
58
+
59
+ NOTE: netzke-basepack is not dependant on neither DataMapper nor Sequel. It will pick the right DataAdapter for your models automatically.
60
+ ActiveRecord is still included in Gemfile of the test app, as netzke-persistance is used which uses ActiveRecord.
61
+ If you don't use netzke-persistence, then you don't need to include ActiveRecord.
62
+
63
+ ## DataMapper support
64
+ DataMapper support is *incomplete*, as I didn't find a good way to sort by an association's column when the association needs a LEFT OUTER JOIN (i.e. nullable foreign key in many_to_one).
65
+
66
+ ## Sequel support
67
+
68
+ CAVEATS:
69
+ - you can't use polymorphic associations for the time being, as the sequel_polymorphic plugin is not supported by netzke-basepack
70
+ - SearchPanel is broken atm. When it's fixed, Sequel support for
71
+ SearchPanel triggered queries should be implemented.
72
+
39
73
  ## Icons support
40
74
  Netzke Basepack can make use of FamFamFam Silk icon set (http://www.famfamfam.com/archive/silk-icons-thats-your-lot/). To enable this, download the icons and put the "icons" folder into your app's public/images folder. Then restart your application.
41
75
 
@@ -57,4 +91,4 @@ Many (if a bit outdated) tutorials: http://blog.writelesscode.com
57
91
 
58
92
  ---
59
93
  Copyright (c) 2008-2011 NomadCoder, released under the MIT license
60
- Note, that Ext JS itself is licensed [differently](http://www.sencha.com/products/extjs/license/)
94
+ Note, that Ext JS itself is licensed [differently](http://www.sencha.com/products/extjs/license/)
data/Rakefile CHANGED
@@ -10,8 +10,6 @@ begin
10
10
  gemspec.homepage = "http://netzke.org"
11
11
  gemspec.authors = ["Sergei Kozlov"]
12
12
  gemspec.add_dependency("netzke-core", "~>0.7.4")
13
- gemspec.add_dependency("will_paginate", "~>3.0.0")
14
- gemspec.add_dependency("acts_as_list", "~>0.1.4")
15
13
  gemspec.post_install_message = <<-MESSAGE
16
14
 
17
15
  ========================================================================
@@ -60,4 +58,4 @@ namespace :rdoc do
60
58
  task :publish => :rdoc do
61
59
  `scp -r rdoc/* fl:www/api.netzke.org/basepack`
62
60
  end
63
- end
61
+ end
@@ -0,0 +1,28 @@
1
+ # Start xvfb in preparation for cucumber
2
+ sh -e /etc/init.d/xvfb start
3
+
4
+ # fetch extjs
5
+ wget http://extjs.cachefly.net/ext-4.0.2a-gpl.zip
6
+ unzip -q -d test/basepack_test_app/public/ -n ext-4.0.2a-gpl.zip
7
+ mv test/basepack_test_app/public/ext-4.0.2a test/basepack_test_app/public/extjs
8
+
9
+ # cp db configuration
10
+ cp test/basepack_test_app/config/database.yml.travis test/basepack_test_app/config/database.yml
11
+
12
+ # create mysql database
13
+ mysql -e 'create database nbt_test;'
14
+
15
+ # clone netzke-core and netzke-persistence gems into test project
16
+ mkdir -p test/basepack_test_app/vendor/gems
17
+ cd test/basepack_test_app/vendor/gems
18
+ git clone git://github.com/skozlov/netzke-core.git
19
+ cd netzke-core
20
+ git checkout tags/v0.7.4
21
+ cd ..
22
+ git clone git://github.com/skozlov/netzke-persistence.git
23
+ cd netzke-persistence
24
+ git checkout tags/v0.1.0
25
+ cd ../../..
26
+ bundle install
27
+ bundle exec rake db:migrate RAILS_ENV=test
28
+ cd ../..
@@ -7,12 +7,14 @@ module Netzke
7
7
  end
8
8
  end
9
9
 
10
- # Extend ActiveRecord
11
- ActiveRecord::Base.class_eval do
12
- include ::Netzke::ActiveRecord::Attributes
13
- include ::Netzke::ActiveRecord::ComboboxOptions
14
- end
10
+ if defined? ActiveRecord
11
+ # Extend ActiveRecord
12
+ ActiveRecord::Base.class_eval do
13
+ include ::Netzke::ActiveRecord::Attributes
14
+ include ::Netzke::ActiveRecord::ComboboxOptions
15
+ end
15
16
 
16
- ActiveRecord::Relation.class_eval do
17
- include ::Netzke::ActiveRecord::RelationExtensions
18
- end
17
+ ActiveRecord::Relation.class_eval do
18
+ include ::Netzke::ActiveRecord::RelationExtensions
19
+ end
20
+ end
@@ -3,14 +3,28 @@ module Netzke
3
3
  module Attributes
4
4
  extend ActiveSupport::Concern
5
5
 
6
+ included do
7
+ class_attribute :netzke_declared_attr
8
+ self.netzke_declared_attr = []
9
+
10
+ class_attribute :netzke_excluded_attr
11
+ self.netzke_excluded_attr = []
12
+
13
+ class_attribute :netzke_exposed_attr
14
+ end
15
+
6
16
  module ClassMethods
17
+ def data_adapter
18
+ @data_adapter = Netzke::Basepack::DataAdapters::AbstractAdapter.adapter_class(self).new(self)
19
+ end
20
+
7
21
  # Define or configure an attribute.
8
22
  # Example:
9
23
  # netzke_attribute :recent, :type => :boolean, :read_only => true
10
24
  def netzke_attribute(name, options = {})
11
25
  name = name.to_s
12
26
  options[:attr_type] = options.delete(:type) || options.delete(:attr_type) || :string
13
- declared_attrs = read_inheritable_attribute(:netzke_declared_attributes) || []
27
+ declared_attrs = self.netzke_declared_attr.dup
14
28
  # if the attr was declared already, simply merge it with the new options
15
29
  existing = declared_attrs.detect{ |va| va[:name] == name }
16
30
  if existing
@@ -24,7 +38,7 @@ module Netzke
24
38
  declared_attrs << {:name => name}.merge(options)
25
39
  end
26
40
  end
27
- write_inheritable_attribute(:netzke_declared_attributes, declared_attrs)
41
+ self.netzke_declared_attr = declared_attrs
28
42
  end
29
43
 
30
44
  # Exclude attributes from being picked up by grids and forms.
@@ -32,7 +46,7 @@ module Netzke
32
46
  # Example:
33
47
  # netzke_expose_attributes :created_at, :updated_at, :crypted_password
34
48
  def netzke_exclude_attributes(*args)
35
- write_inheritable_attribute(:netzke_excluded_attributes, args.map(&:to_s))
49
+ self.netzke_excluded_attr = args.map(&:to_s)
36
50
  end
37
51
 
38
52
  # Explicitly expose attributes that should be picked up by grids and forms.
@@ -41,7 +55,7 @@ module Netzke
41
55
  # Example:
42
56
  # netzke_expose_attributes :name, :role__name
43
57
  def netzke_expose_attributes(*args)
44
- write_inheritable_attribute(:netzke_exposed_attributes, args.map(&:to_s))
58
+ self.netzke_exposed_attr = args.map(&:to_s)
45
59
  end
46
60
 
47
61
  # Returns the attributes that will be picked up by grids and forms.
@@ -55,7 +69,7 @@ module Netzke
55
69
  end
56
70
 
57
71
  def netzke_exposed_attributes
58
- exposed = read_inheritable_attribute(:netzke_exposed_attributes)
72
+ exposed = self.netzke_exposed_attr
59
73
  if exposed && !exposed.include?(self.primary_key)
60
74
  # automatically declare primary key as a netzke attribute
61
75
  netzke_attribute(self.primary_key)
@@ -65,17 +79,10 @@ module Netzke
65
79
  end
66
80
 
67
81
  private
68
- def netzke_declared_attributes
69
- read_inheritable_attribute(:netzke_declared_attributes) || []
70
- end
71
-
72
- def netzke_excluded_attributes
73
- read_inheritable_attribute(:netzke_excluded_attributes) || []
74
- end
75
82
 
76
83
  def netzke_attrs_in_forced_order(attrs)
77
84
  attrs.collect do |attr_name|
78
- declared = netzke_declared_attributes.detect { |va| va[:name] == attr_name } || {}
85
+ declared = self.netzke_declared_attr.detect { |va| va[:name] == attr_name } || {}
79
86
  in_columns_hash = columns_hash[attr_name] && {:name => attr_name, :attr_type => columns_hash[attr_name].type, :default_value => columns_hash[attr_name].default} || {} # {:virtual => true} # if nothing found in columns, mark it as "virtual" or not?
80
87
  if in_columns_hash.empty?
81
88
  # If not among the model columns, it's either virtual, or an association
@@ -98,7 +105,7 @@ module Netzke
98
105
  # role_id => role__name
99
106
  def netzke_attrs_in_natural_order
100
107
  (
101
- declared_attrs = netzke_declared_attributes
108
+ declared_attrs = self.netzke_declared_attr
102
109
 
103
110
  column_names.map do |name|
104
111
  c = {:name => name, :attr_type => columns_hash[name].type}
@@ -124,7 +131,7 @@ module Netzke
124
131
  c
125
132
  end +
126
133
  declared_attrs
127
- ).reject { |attr| netzke_excluded_attributes.include?(attr[:name]) }
134
+ ).reject { |attr| self.netzke_excluded_attr.include?(attr[:name]) }
128
135
  end
129
136
 
130
137
  # Returns foreign key for given association (Rails >= 3.0)
@@ -139,7 +146,7 @@ module Netzke
139
146
  end
140
147
 
141
148
  # Transforms a record to array of values according to the passed attributes
142
- def to_array(attributes)
149
+ def netzke_array(attributes = self.class.netzke_attributes)
143
150
  res = []
144
151
  for a in attributes
145
152
  next if a[:included] == false
@@ -148,8 +155,12 @@ module Netzke
148
155
  res
149
156
  end
150
157
 
158
+ def netzke_json
159
+ netzke_hash.to_nifty_json
160
+ end
161
+
151
162
  # Accepts both hash and array of attributes
152
- def to_hash(attributes)
163
+ def netzke_hash(attributes = self.class.netzke_attributes)
153
164
  res = {}
154
165
  for a in (attributes.is_a?(Hash) ? attributes.values : attributes)
155
166
  next if a[:included] == false
@@ -11,7 +11,9 @@ module Netzke
11
11
  params.empty? ? self.where(scope) : self.where([scope, *params])
12
12
  when "Array"
13
13
  self.extend_with(*scope)
14
- when "Hash" # conditions hash
14
+ when "Hash" # conditions hash
15
+ self.where(scope)
16
+ when "ActiveSupport::HashWithIndifferentAccess" # conditions hash
15
17
  self.where(scope)
16
18
  when "Proc" # receives a relation, must return a relation
17
19
  scope.call(self)
@@ -3,9 +3,17 @@ require 'netzke/basepack/version'
3
3
  if defined? ActiveRecord
4
4
  require 'netzke/active_record'
5
5
  end
6
+ if defined? DataMapper
7
+ require 'netzke/data_mapper'
8
+ end
9
+ if defined? Sequel
10
+ require 'netzke/sequel'
11
+ end
6
12
 
7
- # will_paginate supports more than just ActiveRecord
8
- require 'will_paginate'
13
+ require 'netzke/basepack/data_adapters/abstract_adapter'
14
+ require 'netzke/basepack/data_adapters/active_record_adapter' if defined? ActiveRecord
15
+ require 'netzke/basepack/data_adapters/data_mapper_adapter' if defined? DataMapper
16
+ require 'netzke/basepack/data_adapters/sequel_adapter' if defined? Sequel
9
17
 
10
18
  module Netzke
11
19
  module Basepack
@@ -4,20 +4,18 @@ module Netzke
4
4
  extend ActiveSupport::Concern
5
5
 
6
6
  included do |base|
7
+
8
+ # Returns registered actions
9
+ class_attribute :registered_column_actions
10
+ self.registered_column_actions = []
11
+
7
12
  js_include :action_column
8
13
  end
9
14
 
10
15
  module ClassMethods
11
16
  # Register an action
12
17
  def register_column_action(name)
13
- current_column_actions = read_inheritable_attribute(:column_actions) || []
14
- current_column_actions << name
15
- write_inheritable_attribute(:column_actions, current_column_actions.uniq)
16
- end
17
-
18
- # Returns registered actions
19
- def registered_column_actions
20
- read_inheritable_attribute(:column_actions) || []
18
+ self.registered_column_actions |= [name]
21
19
  end
22
20
 
23
21
  # Use this method to define column actions in your component, e.g.:
@@ -3,48 +3,11 @@ module Netzke
3
3
  # This module is included into such data-driven components as GridPanel, FormPanel, PagingFormPanel, etc.
4
4
  module DataAccessor
5
5
 
6
- # Returns options for comboboxes in grids/forms
7
- def combobox_options_for_column(column, method_options = {})
8
- query = method_options[:query]
9
-
10
- # First, check if we have options for this column defined in persistent storage
11
- options = column[:combobox_options] && column[:combobox_options].split("\n")
12
- if options
13
- query ? options.select{ |o| o.index(/^#{query}/) }.map{ |el| [el] } : options
14
- else
15
- assoc, assoc_method = assoc_and_assoc_method_for_attr(column)
16
-
17
- if assoc
18
- # Options for an asssociation attribute
19
-
20
- relation = assoc.klass.scoped
21
6
 
22
- relation = relation.extend_with(method_options[:scope]) if method_options[:scope]
23
7
 
24
- if assoc.klass.column_names.include?(assoc_method)
25
- # apply query
26
- relation = relation.where(["#{assoc_method} like ?", "%#{query}%"]) if query.present?
27
- relation.all.map{ |r| [r.id, r.send(assoc_method)] }
28
- else
29
- relation.all.map{ |r| [r.id, r.send(assoc_method)] }.select{ |id,value| value =~ /^#{query}/ }
30
- end
31
-
32
- else
33
- # Options for a non-association attribute
34
- res=data_class.netzke_combo_options_for(column[:name], method_options)
35
-
36
- # ensure it is an array-in-array, as Ext will fail otherwise
37
- raise RuntimeError, "netzke_combo_options_for should return an Array" unless res.kind_of? Array
38
- return [[]] if res.empty?
39
-
40
- unless res.first.kind_of? Array
41
- res=res.map do |v|
42
- [v]
43
- end
44
- end
45
- return res
46
- end
47
- end
8
+ # Returns options for comboboxes in grids/forms
9
+ def combobox_options_for_column(column, method_options = {})
10
+ data_adapter.combobox_options_for_column column, method_options
48
11
  end
49
12
 
50
13
  # Normalize array of attributes
@@ -61,156 +24,30 @@ module Netzke
61
24
  a.is_a?(Symbol) || a.is_a?(String) ? {:name => a.to_s} : a.merge(:name => a[:name].to_s)
62
25
  end
63
26
 
64
- # Returns association and association method for a column
65
- def assoc_and_assoc_method_for_attr(c)
66
- assoc_name, assoc_method = c[:name].split('__')
67
- assoc = data_class.reflect_on_association(assoc_name.to_sym) if assoc_method
68
- [assoc, assoc_method]
69
- end
70
-
71
27
  def association_attr?(name)
72
28
  !!name.to_s.index("__")
73
29
  end
74
30
 
75
31
  # Model class
76
32
  def data_class
77
- @data_class ||= config[:model] && config[:model].constantize
33
+ @data_class ||= config[:model].is_a?(String) ? config[:model].constantize : config[:model]
34
+ end
35
+
36
+ # Data adapter responsible for all DB-related operations
37
+ def data_adapter
38
+ @data_adapter ||= Netzke::Basepack::DataAdapters::AbstractAdapter.adapter_class(data_class).new(data_class)
78
39
  end
79
40
 
80
41
  # whether a column is bound to the primary_key
81
42
  def primary_key_attr?(a)
82
- data_class && a[:name].to_s == data_class.primary_key
43
+ data_class && a[:name].to_s == data_class.primary_key.to_s
83
44
  end
84
45
 
85
46
  # Mark an attribute as "virtual" by default, when it doesn't reflect a model column, or a model column of an association
86
47
  def set_default_virtual(c)
87
- if c[:virtual].nil? # sometimes at maybe handy to mark a column as non-virtual forcefully
88
- assoc, assoc_method = assoc_and_assoc_method_for_attr(c)
89
- if assoc
90
- c[:virtual] = true if !assoc.klass.column_names.map(&:to_sym).include?(assoc_method.to_sym)
91
- else
92
- c[:virtual] = true if !data_class.column_names.map(&:to_sym).include?(c[:name].to_sym)
93
- end
94
- end
95
- end
96
-
97
- # An ActiveRecord::Relation instance encapsulating all the necessary conditions.
98
- def get_relation(params = {})
99
- @arel = data_class.arel_table
100
-
101
- relation = data_class.scoped
102
-
103
- relation = apply_column_filters(relation, params[:filter]) if params[:filter]
104
-
105
- if params[:extra_conditions]
106
- extra_conditions = normalize_extra_conditions(ActiveSupport::JSON.decode(params[:extra_conditions]))
107
- relation = relation.extend_with_netzke_conditions(extra_conditions) if params[:extra_conditions]
108
- end
109
-
110
- query = params[:query] && ActiveSupport::JSON.decode(params[:query])
111
-
112
- if query.present?
113
- # array of arrays of conditions that should be joined by OR
114
- and_predicates = query.map do |conditions|
115
- predicates_for_and_conditions(conditions)
116
- end
117
-
118
- # join them by OR
119
- predicates = and_predicates[1..-1].inject(and_predicates.first){ |r,c| r.or(c) }
120
- end
121
-
122
- relation = relation.where(predicates)
123
-
124
- relation = relation.extend_with(config[:scope]) if config[:scope]
125
-
126
- relation
48
+ c[:virtual] = data_adapter.column_virtual?(c) if c[:virtual].nil?
127
49
  end
128
50
 
129
- # Parses and applies grid column filters, calling consequent "where" methods on the passed relation.
130
- # Returns the updated relation.
131
- #
132
- # Example column grid data:
133
- #
134
- # {"0" => {
135
- # "data" => {
136
- # "type" => "numeric",
137
- # "comparison" => "gt",
138
- # "value" => 10 },
139
- # "field" => "id"
140
- # },
141
- # "1" => {
142
- # "data" => {
143
- # "type" => "string",
144
- # "value" => "pizza"
145
- # },
146
- # "field" => "food_name"
147
- # }}
148
- #
149
- # This will result in:
150
- #
151
- # relation.where(["id > ?", 10]).where(["food_name like ?", "%pizza%"])
152
- def apply_column_filters(relation, column_filter)
153
- res = relation
154
- operator_map = {"lt" => "<", "gt" => ">", "eq" => "="}
155
-
156
- table_name = data_class.table_name
157
-
158
- # these are still JSON-encoded due to the migration to Ext.direct
159
- column_filter=JSON.parse(column_filter)
160
- column_filter.each do |v|
161
- assoc, method = v["field"].split('__')
162
- if method
163
- assoc = data_class.reflect_on_association(assoc.to_sym)
164
- field = [assoc.klass.table_name, method].join('.')
165
- else
166
- field = [table_name, assoc].join('.')
167
- end
168
-
169
- value = v["value"]
170
-
171
- op = operator_map[v['comparison']]
172
-
173
- case v["type"]
174
- when "string"
175
- res = res.where(["#{field} like ?", "%#{value}%"])
176
- when "date"
177
- # convert value to the DB date
178
- value.match /(\d\d)\/(\d\d)\/(\d\d\d\d)/
179
- res = res.where("#{field} #{op} ?", "#{$3}-#{$1}-#{$2}")
180
- when "numeric"
181
- res = res.where(["#{field} #{op} ?", value])
182
- else
183
- res = res.where(["#{field} = ?", value])
184
- end
185
- end
186
-
187
- res
188
- end
189
-
190
-
191
- protected
192
-
193
- def predicates_for_and_conditions(conditions)
194
- return nil if conditions.empty?
195
-
196
- predicates = conditions.map do |q|
197
- value = q["value"]
198
- case q["operator"]
199
- when "contains"
200
- @arel[q["attr"]].matches "%#{value}%"
201
- else
202
- if value == false || value == true
203
- @arel[q["attr"]].eq(value ? 1 : 0)
204
- else
205
- @arel[q["attr"]].send(q["operator"], value)
206
- end
207
- end
208
- end
209
-
210
- # join them by AND
211
- predicates[1..-1].inject(predicates.first){ |r,p| r.and(p) }
212
- end
213
-
214
51
  end
215
52
  end
216
53
  end