graphiti 1.2.16 → 1.2.17

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +43 -14
  3. data/Appraisals +37 -5
  4. data/Guardfile +4 -4
  5. data/deprecated_generators/graphiti/resource_generator.rb +1 -1
  6. data/gemfiles/rails_5_0.gemfile +18 -0
  7. data/gemfiles/rails_5_0_graphiti_rails.gemfile +20 -0
  8. data/gemfiles/rails_5_1.gemfile +18 -0
  9. data/gemfiles/rails_5_1_graphiti_rails.gemfile +20 -0
  10. data/gemfiles/{rails_5.gemfile → rails_5_2.gemfile} +0 -0
  11. data/gemfiles/{rails_5_graphiti_rails.gemfile → rails_5_2_graphiti_rails.gemfile} +0 -0
  12. data/gemfiles/rails_6.gemfile +1 -1
  13. data/gemfiles/rails_6_graphiti_rails.gemfile +1 -1
  14. data/graphiti.gemspec +10 -10
  15. data/lib/graphiti.rb +3 -3
  16. data/lib/graphiti/adapters/abstract.rb +3 -3
  17. data/lib/graphiti/adapters/active_record.rb +64 -35
  18. data/lib/graphiti/configuration.rb +1 -1
  19. data/lib/graphiti/debugger.rb +4 -4
  20. data/lib/graphiti/delegates/pagination.rb +3 -3
  21. data/lib/graphiti/deserializer.rb +3 -3
  22. data/lib/graphiti/errors.rb +24 -4
  23. data/lib/graphiti/query.rb +4 -4
  24. data/lib/graphiti/railtie.rb +1 -1
  25. data/lib/graphiti/request_validator.rb +4 -4
  26. data/lib/graphiti/request_validators/update_validator.rb +1 -2
  27. data/lib/graphiti/request_validators/validator.rb +2 -2
  28. data/lib/graphiti/resource/configuration.rb +6 -4
  29. data/lib/graphiti/resource/dsl.rb +5 -4
  30. data/lib/graphiti/resource/links.rb +3 -3
  31. data/lib/graphiti/resource/persistence.rb +2 -1
  32. data/lib/graphiti/resource/polymorphism.rb +2 -1
  33. data/lib/graphiti/resource/remote.rb +1 -1
  34. data/lib/graphiti/runner.rb +1 -1
  35. data/lib/graphiti/schema.rb +6 -6
  36. data/lib/graphiti/scope.rb +5 -5
  37. data/lib/graphiti/scoping/base.rb +3 -3
  38. data/lib/graphiti/scoping/filter.rb +17 -7
  39. data/lib/graphiti/scoping/sort.rb +1 -1
  40. data/lib/graphiti/sideload.rb +26 -22
  41. data/lib/graphiti/sideload/belongs_to.rb +1 -1
  42. data/lib/graphiti/stats/payload.rb +4 -4
  43. data/lib/graphiti/types.rb +15 -15
  44. data/lib/graphiti/util/link.rb +5 -1
  45. data/lib/graphiti/util/persistence.rb +16 -10
  46. data/lib/graphiti/util/relationship_payload.rb +4 -4
  47. data/lib/graphiti/util/simple_errors.rb +1 -1
  48. data/lib/graphiti/util/transaction_hooks_recorder.rb +1 -1
  49. data/lib/graphiti/version.rb +1 -1
  50. metadata +8 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1cf06fc44b5ea470fcaaa4eb090abec15ce864b116f7dcb57d76dd9ca97c41ba
4
- data.tar.gz: 5b60d753e401ff3cc93613f064de5c686746c855033f9ef046616426222cc379
3
+ metadata.gz: af3b1ec7bee727eb7526b6ce3057576e323f029bdda9f57447021973fa35b2ed
4
+ data.tar.gz: 34deda0508ba3d23299272cb387cc19a3f90e90ee1f084b930858488dcf1222b
5
5
  SHA512:
6
- metadata.gz: f5e22a684fccd5b670c22423dead0bac0ec3d242157f5f8f2e030c7469c6f951471d161168f0f7bd75c0ab05c5a5e04b88d7b0002750746e583719a6b50f3215
7
- data.tar.gz: fdd3d58e32f14d3437ff4d4d5d0cc8619ca78673a3d37f83393e6957462218d9a7904df2f6690ab6a8eb1595e80b4f3ab63380d978a7d9b4d69ab03cb3f1bd8e
6
+ metadata.gz: 649b13c8e55456bfe9a06a9c26cdb36cd345e69137b50afc3c0861b77c334841b5cccb993d1b263986bc2e385e2fb8c28a64c718ff734ccffadb5e3b2d7d76eb
7
+ data.tar.gz: f78993e3439b19afb85520c9955415ac03a4332eefc9f683828a2da0cd999b933f07b50df141e1d305ecd3799c9bef3142d4af2020bb356694ce97872b7f80c9
@@ -3,45 +3,74 @@ language: ruby
3
3
  rvm:
4
4
  - 2.5
5
5
  - 2.6
6
+ - 2.7
6
7
  gemfile:
7
8
  - Gemfile
8
9
  - gemfiles/rails_4.gemfile
9
- - gemfiles/rails_5.gemfile
10
+ - gemfiles/rails_5_0.gemfile
11
+ - gemfiles/rails_5_1.gemfile
12
+ - gemfiles/rails_5_2.gemfile
10
13
  - gemfiles/rails_6.gemfile
11
- - gemfiles/rails_5_graphiti_rails.gemfile
14
+ - gemfiles/rails_5_0_graphiti_rails.gemfile
15
+ - gemfiles/rails_5_1_graphiti_rails.gemfile
16
+ - gemfiles/rails_5_2_graphiti_rails.gemfile
12
17
  - gemfiles/rails_6_graphiti_rails.gemfile
13
18
  env:
14
- - COMMAND=standardrb --no-fix --format progress
19
+ - COMMAND="standardrb --no-fix --format progress"
15
20
  - COMMAND=rspec
16
21
  - COMMAND=rspec APPRAISAL_INITIALIZED=true
17
22
  matrix:
18
23
  exclude:
19
- - env: COMMAND=standardrb --no-fix --format progress
24
+ # Don't run the appraisal version of the specs for the base gemfile
25
+ - env: COMMAND=rspec APPRAISAL_INITIALIZED=true
26
+ gemfile: Gemfile
27
+ # Don't run the standardrb check on any gemfile except the base gemfile
28
+ # (but run it for each ruby version)
29
+ - env: COMMAND="standardrb --no-fix --format progress"
20
30
  gemfile: gemfiles/rails_4.gemfile
21
- - env: COMMAND=standardrb --no-fix --format progress
22
- gemfile: gemfiles/rails_5.gemfile
23
- - env: COMMAND=standardrb --no-fix --format progress
31
+ - env: COMMAND="standardrb --no-fix --format progress"
32
+ gemfile: gemfiles/rails_5_0.gemfile
33
+ - env: COMMAND="standardrb --no-fix --format progress"
34
+ gemfile: gemfiles/rails_5_1.gemfile
35
+ - env: COMMAND="standardrb --no-fix --format progress"
36
+ gemfile: gemfiles/rails_5_2.gemfile
37
+ - env: COMMAND="standardrb --no-fix --format progress"
24
38
  gemfile: gemfiles/rails_6.gemfile
25
- - env: COMMAND=standardrb --no-fix --format progress
26
- gemfile: gemfiles/rails_5_graphiti_rails.gemfile
27
- - env: COMMAND=standardrb --no-fix --format progress
39
+ - env: COMMAND="standardrb --no-fix --format progress"
40
+ gemfile: gemfiles/rails_5_0_graphiti_rails.gemfile
41
+ - env: COMMAND="standardrb --no-fix --format progress"
42
+ gemfile: gemfiles/rails_5_1_graphiti_rails.gemfile
43
+ - env: COMMAND="standardrb --no-fix --format progress"
44
+ gemfile: gemfiles/rails_5_2_graphiti_rails.gemfile
45
+ - env: COMMAND="standardrb --no-fix --format progress"
28
46
  gemfile: gemfiles/rails_6_graphiti_rails.gemfile
29
- - env: COMMAND=rspec APPRAISAL_INITIALIZED=true
30
- gemfile: Gemfile
47
+ # Don't run the basic versions of the specs for any of the specific gemfiles
31
48
  - env: COMMAND=rspec
32
49
  gemfile: gemfiles/rails_4.gemfile
33
50
  - env: COMMAND=rspec
34
- gemfile: gemfiles/rails_5.gemfile
51
+ gemfile: gemfiles/rails_5_0.gemfile
52
+ - env: COMMAND=rspec
53
+ gemfile: gemfiles/rails_5_1.gemfile
54
+ - env: COMMAND=rspec
55
+ gemfile: gemfiles/rails_5_2.gemfile
35
56
  - env: COMMAND=rspec
36
57
  gemfile: gemfiles/rails_6.gemfile
37
58
  - env: COMMAND=rspec
38
- gemfile: gemfiles/rails_5_graphiti_rails.gemfile
59
+ gemfile: gemfiles/rails_5_0_graphiti_rails.gemfile
60
+ - env: COMMAND=rspec
61
+ gemfile: gemfiles/rails_5_1_graphiti_rails.gemfile
62
+ - env: COMMAND=rspec
63
+ gemfile: gemfiles/rails_5_2_graphiti_rails.gemfile
39
64
  - env: COMMAND=rspec
40
65
  gemfile: gemfiles/rails_6_graphiti_rails.gemfile
66
+
67
+ # Don't run rails 4 egmfile against any rubies (for some reason?)
41
68
  - gemfile: gemfiles/rails_4.gemfile
42
69
  rvm: 2.5
43
70
  - gemfile: gemfiles/rails_4.gemfile
44
71
  rvm: 2.6
72
+ - gemfile: gemfiles/rails_4.gemfile
73
+ rvm: 2.7
45
74
 
46
75
  script:
47
76
  - bundle _1.17.3_ exec $COMMAND
data/Appraisals CHANGED
@@ -1,18 +1,50 @@
1
1
  appraise "rails-4" do
2
- gem "rails", "~> 4.1"
2
+ gem "rails", "~> 4.2"
3
3
  gem "rspec-rails"
4
4
  gem "sqlite3", "~> 1.3.6"
5
5
  gem "database_cleaner"
6
6
  end
7
7
 
8
- appraise "rails-5" do
8
+ appraise "rails-5_0" do
9
+ gem "rails", "~> 5.0"
10
+ gem "rspec-rails"
11
+ gem "sqlite3", "~> 1.3.6"
12
+ gem "database_cleaner"
13
+ end
14
+
15
+ appraise "rails-5_1" do
16
+ gem "rails", "~> 5.1"
17
+ gem "rspec-rails"
18
+ gem "sqlite3", "~> 1.3.6"
19
+ gem "database_cleaner"
20
+ end
21
+
22
+ appraise "rails-5_2" do
9
23
  gem "rails", "~> 5.2"
10
24
  gem "rspec-rails"
11
25
  gem "sqlite3", "~> 1.3.6"
12
26
  gem "database_cleaner"
13
27
  end
14
28
 
15
- appraise "rails-5-graphiti-rails" do
29
+ appraise "rails-5_0-graphiti-rails" do
30
+ gem "rails", "~> 5.0"
31
+ gem "rspec-rails"
32
+ gem "sqlite3", "~> 1.3.6"
33
+ gem "database_cleaner"
34
+ gem "rescue_registry", git: "https://github.com/wagenet/rescue_registry.git", branch: "master"
35
+ gem "graphiti-rails", git: "https://github.com/wagenet/graphiti-rails.git", branch: "master"
36
+ end
37
+
38
+ appraise "rails-5_1-graphiti-rails" do
39
+ gem "rails", "~> 5.1"
40
+ gem "rspec-rails"
41
+ gem "sqlite3", "~> 1.3.6"
42
+ gem "database_cleaner"
43
+ gem "rescue_registry", git: "https://github.com/wagenet/rescue_registry.git", branch: "master"
44
+ gem "graphiti-rails", git: "https://github.com/wagenet/graphiti-rails.git", branch: "master"
45
+ end
46
+
47
+ appraise "rails-5_2-graphiti-rails" do
16
48
  gem "rails", "~> 5.2"
17
49
  gem "rspec-rails"
18
50
  gem "sqlite3", "~> 1.3.6"
@@ -22,14 +54,14 @@ appraise "rails-5-graphiti-rails" do
22
54
  end
23
55
 
24
56
  appraise "rails-6" do
25
- gem "rails", "~> 6.0.0.rc1"
57
+ gem "rails", "~> 6.0"
26
58
  gem "rspec-rails"
27
59
  gem "sqlite3", "~> 1.4.0"
28
60
  gem "database_cleaner"
29
61
  end
30
62
 
31
63
  appraise "rails-6-graphiti-rails" do
32
- gem "rails", "~> 6.0.0.rc1"
64
+ gem "rails", "~> 6.0"
33
65
  gem "rspec-rails"
34
66
  gem "sqlite3", "~> 1.4.0"
35
67
  gem "database_cleaner"
data/Guardfile CHANGED
@@ -21,12 +21,12 @@ guard :rspec, cmd: "bundle exec rspec --color --format documentation" do
21
21
  watch(rails.controllers) do |m|
22
22
  [
23
23
  rspec.spec.call("controllers/#{m[1]}_controller"),
24
- rspec.spec.call("api/#{m[1]}"),
24
+ rspec.spec.call("api/#{m[1]}")
25
25
  ]
26
26
  end
27
27
 
28
28
  # Rails config changes
29
- watch(rails.spec_helper) { rspec.spec_dir }
30
- watch(rails.routes) { "#{rspec.spec_dir}/routing" }
31
- watch(rails.app_controller) { "#{rspec.spec_dir}/controllers" }
29
+ watch(rails.spec_helper) { rspec.spec_dir }
30
+ watch(rails.routes) { "#{rspec.spec_dir}/routing" }
31
+ watch(rails.app_controller) { "#{rspec.spec_dir}/controllers" }
32
32
  end
@@ -93,7 +93,7 @@ module Graphiti
93
93
  raise "Unable to set #{self} default_attributes from #{attributes_class}. #{attributes_class} must be a kind of ApplicationRecord"
94
94
  end
95
95
  if attributes_class.table_exists?
96
- return attributes_class.columns.map do |c|
96
+ attributes_class.columns.map do |c|
97
97
  OpenStruct.new({name: c.name.to_sym, type: c.type})
98
98
  end
99
99
  else
@@ -0,0 +1,18 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rails", "~> 5.0"
6
+ gem "rspec-rails"
7
+ gem "sqlite3", "~> 1.3.6"
8
+ gem "database_cleaner"
9
+
10
+ group :test do
11
+ gem "pry"
12
+ gem "pry-byebug", platform: [:mri]
13
+ gem "appraisal"
14
+ gem "guard"
15
+ gem "guard-rspec"
16
+ end
17
+
18
+ gemspec path: "../"
@@ -0,0 +1,20 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rails", "~> 5.0"
6
+ gem "rspec-rails"
7
+ gem "sqlite3", "~> 1.3.6"
8
+ gem "database_cleaner"
9
+ gem "rescue_registry", git: "https://github.com/wagenet/rescue_registry.git", branch: "master"
10
+ gem "graphiti-rails", git: "https://github.com/wagenet/graphiti-rails.git", branch: "master"
11
+
12
+ group :test do
13
+ gem "pry"
14
+ gem "pry-byebug", platform: [:mri]
15
+ gem "appraisal"
16
+ gem "guard"
17
+ gem "guard-rspec"
18
+ end
19
+
20
+ gemspec path: "../"
@@ -0,0 +1,18 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rails", "~> 5.1"
6
+ gem "rspec-rails"
7
+ gem "sqlite3", "~> 1.3.6"
8
+ gem "database_cleaner"
9
+
10
+ group :test do
11
+ gem "pry"
12
+ gem "pry-byebug", platform: [:mri]
13
+ gem "appraisal"
14
+ gem "guard"
15
+ gem "guard-rspec"
16
+ end
17
+
18
+ gemspec path: "../"
@@ -0,0 +1,20 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rails", "~> 5.1"
6
+ gem "rspec-rails"
7
+ gem "sqlite3", "~> 1.3.6"
8
+ gem "database_cleaner"
9
+ gem "rescue_registry", git: "https://github.com/wagenet/rescue_registry.git", branch: "master"
10
+ gem "graphiti-rails", git: "https://github.com/wagenet/graphiti-rails.git", branch: "master"
11
+
12
+ group :test do
13
+ gem "pry"
14
+ gem "pry-byebug", platform: [:mri]
15
+ gem "appraisal"
16
+ gem "guard"
17
+ gem "guard-rspec"
18
+ end
19
+
20
+ gemspec path: "../"
@@ -2,7 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "rails", "~> 6.0.0"
5
+ gem "rails", "~> 6.0"
6
6
  gem "rspec-rails"
7
7
  gem "sqlite3", "~> 1.4.0"
8
8
  gem "database_cleaner"
@@ -2,7 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "rails", "~> 6.0.0"
5
+ gem "rails", "~> 6.0"
6
6
  gem "rspec-rails"
7
7
  gem "sqlite3", "~> 1.4.0"
8
8
  gem "database_cleaner"
@@ -3,18 +3,18 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
3
  require "graphiti/version"
4
4
 
5
5
  Gem::Specification.new do |spec|
6
- spec.name = "graphiti"
7
- spec.version = Graphiti::VERSION
8
- spec.authors = ["Lee Richmond"]
9
- spec.email = ["richmolj@gmail.com"]
6
+ spec.name = "graphiti"
7
+ spec.version = Graphiti::VERSION
8
+ spec.authors = ["Lee Richmond"]
9
+ spec.email = ["richmolj@gmail.com"]
10
10
 
11
- spec.summary = "Easily build jsonapi.org-compatible APIs"
12
- spec.homepage = "https://github.com/graphiti-api/graphiti"
13
- spec.license = "MIT"
11
+ spec.summary = "Easily build jsonapi.org-compatible APIs"
12
+ spec.homepage = "https://github.com/graphiti-api/graphiti"
13
+ spec.license = "MIT"
14
14
 
15
- spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
16
- spec.bindir = "exe"
17
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
15
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
16
+ spec.bindir = "exe"
17
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
18
18
  spec.require_paths = ["lib"]
19
19
  spec.required_ruby_version = "~> 2.3"
20
20
 
@@ -13,7 +13,7 @@ require "graphiti_errors"
13
13
  require "jsonapi/serializable"
14
14
 
15
15
  module Graphiti
16
- DEPRECATOR = ActiveSupport::Deprecation.new('2.0', 'Graphiti')
16
+ DEPRECATOR = ActiveSupport::Deprecation.new("2.0", "Graphiti")
17
17
 
18
18
  # @api private
19
19
  def self.context
@@ -33,9 +33,9 @@ module Graphiti
33
33
  ensure
34
34
  self.context = prior
35
35
 
36
- resources.each { |resource_class|
36
+ resources.each do |resource_class|
37
37
  resource_class.sideloads.values.each(&:clear_resources)
38
- }
38
+ end
39
39
  end
40
40
 
41
41
  def self.config
@@ -17,7 +17,7 @@ module Graphiti
17
17
  belongs_to: ::Graphiti::Sideload::BelongsTo,
18
18
  has_one: ::Graphiti::Sideload::HasOne,
19
19
  many_to_many: ::Graphiti::Sideload::ManyToMany,
20
- polymorphic_belongs_to: ::Graphiti::Sideload::PolymorphicBelongsTo,
20
+ polymorphic_belongs_to: ::Graphiti::Sideload::PolymorphicBelongsTo
21
21
  }
22
22
  end
23
23
 
@@ -33,7 +33,7 @@ module Graphiti
33
33
  :suffix,
34
34
  :not_suffix,
35
35
  :match,
36
- :not_match,
36
+ :not_match
37
37
  ],
38
38
  uuid: [:eq, :not_eq],
39
39
  enum: [:eq, :not_eq],
@@ -45,7 +45,7 @@ module Graphiti
45
45
  date: numerical_operators,
46
46
  datetime: numerical_operators,
47
47
  hash: [:eq],
48
- array: [:eq],
48
+ array: [:eq]
49
49
  }
50
50
  end
51
51
 
@@ -12,7 +12,7 @@ module Graphiti
12
12
  has_many: Graphiti::Adapters::ActiveRecord::HasManySideload,
13
13
  has_one: Graphiti::Adapters::ActiveRecord::HasOneSideload,
14
14
  belongs_to: Graphiti::Adapters::ActiveRecord::BelongsToSideload,
15
- many_to_many: Graphiti::Adapters::ActiveRecord::ManyToManySideload,
15
+ many_to_many: Graphiti::Adapters::ActiveRecord::ManyToManySideload
16
16
  }
17
17
  end
18
18
 
@@ -57,52 +57,61 @@ module Graphiti
57
57
  filter_string_eql(scope, attribute, value, is_not: true)
58
58
  end
59
59
 
60
- def filter_string_prefix(scope, attribute, value, is_not: false)
61
- column = column_for(scope, attribute)
62
- map = value.map { |v| "#{v}%" }
63
- clause = column.lower.matches_any(map)
64
- is_not ? scope.where.not(clause) : scope.where(clause)
65
- end
66
-
67
- def filter_string_not_prefix(scope, attribute, value)
68
- filter_string_prefix(scope, attribute, value, is_not: true)
69
- end
70
-
71
- def filter_string_suffix(scope, attribute, value, is_not: false)
72
- column = column_for(scope, attribute)
73
- map = value.map { |v| "%#{v}" }
74
- clause = column.lower.matches_any(map)
75
- is_not ? scope.where.not(clause) : scope.where(clause)
76
- end
77
-
78
- def filter_string_not_suffix(scope, attribute, value)
79
- filter_string_suffix(scope, attribute, value, is_not: true)
80
- end
81
-
82
60
  # Arel has different match escaping behavior before rails 5.
83
61
  # Since rails 4.x does not expose methods to escape LIKE statements
84
62
  # anyway, we just don't support proper LIKE escaping in those versions.
85
- if ::ActiveRecord.version >= Gem::Version.new('5.0.0')
63
+ if ::ActiveRecord.version >= Gem::Version.new("5.0.0")
86
64
  def filter_string_match(scope, attribute, value, is_not: false)
87
- escape_char = '\\'
88
- column = column_for(scope, attribute)
89
- map = value.map do |v|
90
- v = v.downcase
91
- v = scope.sanitize_sql_like(v)
65
+ clause = sanitized_like_for(scope, attribute, value) { |v|
92
66
  "%#{v}%"
93
- end
94
- clause = column.lower.matches_any(map, escape_char, true)
67
+ }
68
+ is_not ? scope.where.not(clause) : scope.where(clause)
69
+ end
70
+
71
+ def filter_string_prefix(scope, attribute, value, is_not: false)
72
+ clause = sanitized_like_for(scope, attribute, value) { |v|
73
+ "#{v}%"
74
+ }
75
+ is_not ? scope.where.not(clause) : scope.where(clause)
76
+ end
77
+
78
+ def filter_string_suffix(scope, attribute, value, is_not: false)
79
+ clause = sanitized_like_for(scope, attribute, value) { |v|
80
+ "%#{v}"
81
+ }
95
82
  is_not ? scope.where.not(clause) : scope.where(clause)
96
83
  end
97
84
  else
98
85
  def filter_string_match(scope, attribute, value, is_not: false)
99
86
  column = column_for(scope, attribute)
100
- map = value.map do |v|
87
+ map = value.map { |v|
101
88
  "%#{v.downcase}%"
102
- end
89
+ }
90
+ clause = column.lower.matches_any(map)
91
+ is_not ? scope.where.not(clause) : scope.where(clause)
92
+ end
93
+
94
+ def filter_string_prefix(scope, attribute, value, is_not: false)
95
+ column = column_for(scope, attribute)
96
+ map = value.map { |v| "#{v}%" }
103
97
  clause = column.lower.matches_any(map)
104
98
  is_not ? scope.where.not(clause) : scope.where(clause)
105
99
  end
100
+
101
+ def filter_string_suffix(scope, attribute, value, is_not: false)
102
+ column = column_for(scope, attribute)
103
+ map = value.map { |v| "%#{v}" }
104
+ clause = column.lower.matches_any(map)
105
+ is_not ? scope.where.not(clause) : scope.where(clause)
106
+ end
107
+ end
108
+
109
+ def filter_string_not_prefix(scope, attribute, value)
110
+ filter_string_prefix(scope, attribute, value, is_not: true)
111
+ end
112
+
113
+ def filter_string_not_suffix(scope, attribute, value)
114
+ filter_string_suffix(scope, attribute, value, is_not: true)
106
115
  end
107
116
 
108
117
  def filter_string_not_match(scope, attribute, value)
@@ -273,8 +282,8 @@ module Graphiti
273
282
 
274
283
  # (see Adapters::Abstract#update)
275
284
  def update(model_class, update_params)
276
- instance = model_class.find(update_params.delete(:id))
277
- instance.update_attributes(update_params)
285
+ instance = model_class.find(update_params.only(:id))
286
+ instance.update_attributes(update_params.except(:id))
278
287
  instance
279
288
  end
280
289
 
@@ -298,6 +307,26 @@ module Graphiti
298
307
  table[name]
299
308
  end
300
309
  end
310
+
311
+ def sanitized_like_for(scope, attribute, value, &block)
312
+ escape_char = '\\'
313
+ column = column_for(scope, attribute)
314
+ map = value.map { |v|
315
+ v = v.downcase
316
+ v = Sanitizer.sanitize_like(v, escape_char)
317
+ block.call v
318
+ }
319
+
320
+ column.lower.matches_any(map, escape_char, true)
321
+ end
322
+
323
+ class Sanitizer
324
+ extend ::ActiveRecord::Sanitization::ClassMethods
325
+
326
+ def self.sanitize_like(*args)
327
+ sanitize_sql_like(*args)
328
+ end
329
+ end
301
330
  end
302
331
  end
303
332
  end