Skip to content

Commit 247a257

Browse files
author
Michael Crismali
committed
added array_contains scopes
1 parent 9ad18f3 commit 247a257

File tree

2 files changed

+38
-6
lines changed

2 files changed

+38
-6
lines changed

lib/jsonb_accessor/macro.rb

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,11 @@ def __create_jsonb_typed_scopes(jsonb_attribute, fields_map)
7373
when :boolean
7474
___create_jsonb_boolean_scopes(field)
7575
when :integer, :float, :decimal, :big_integer
76-
___create_jsonb_numeric_scopes(field, type, jsonb_attribute)
76+
___create_jsonb_numeric_scopes(field, jsonb_attribute, type)
7777
when :date_time, :date, :time
7878
___create_jsonb_date_time_scopes(field, jsonb_attribute, type)
79+
when /array/
80+
___create_jsonb_array_scopes(field)
7981
end
8082
end
8183
end
@@ -85,9 +87,9 @@ def ___create_jsonb_boolean_scopes(field)
8587
scope "not_#{field}", -> { send("with_#{field}", false) }
8688
end
8789

88-
def ___create_jsonb_numeric_scopes(field, type, jsonb_attribute)
90+
def ___create_jsonb_numeric_scopes(field, jsonb_attribute, type)
8991
safe_type = type.to_s.gsub("big_", "")
90-
scope "__numeric_#{field}_comparator", -> (value, operator) { where("((#{table_name}.#{jsonb_attribute}) ->> ?)::#{safe_type} #{operator} ?", field, value) }
92+
scope "__numeric_#{field}_comparator", -> (value, operator) { where("((#{table_name}.#{jsonb_attribute}) - >> ?)::#{safe_type} #{operator} ?", field, value) }
9193
scope "#{field}_lt", -> (value) { send("__numeric_#{field}_comparator", value, "<") }
9294
scope "#{field}_lte", -> (value) { send("__numeric_#{field}_comparator", value, "<=") }
9395
scope "#{field}_gte", -> (value) { send("__numeric_#{field}_comparator", value, ">=") }
@@ -98,6 +100,10 @@ def ___create_jsonb_date_time_scopes(field, jsonb_attribute, type)
98100
scope "#{field}_before", -> (value) { where("((#{table_name}.#{jsonb_attribute}) ->> ?)::timestamp < ?::timestamp", field, value.to_json) }
99101
end
100102

103+
def ___create_jsonb_array_scopes(field)
104+
scope "#{field}_contains", -> (value) { send("with_#{field}", [value]) }
105+
end
106+
101107
def _create_jsonb_accessor_methods(jsonb_attribute, jsonb_attribute_initialization_method_name, fields_map)
102108
jsonb_accessor_methods = Module.new do
103109
define_method("#{jsonb_attribute}=") do |value|

spec/jsonb_accessor_spec.rb

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -790,9 +790,28 @@
790790
context "scopes" do
791791
let(:title) { "foo" }
792792
let(:right_now) { Time.now }
793-
let!(:ignored_product) { Product.create!(title: "bar") }
794-
let!(:matching_product) { Product.create!(title: title, external_id: 3, admin: true, a_big_number: 23, reviewed_at: right_now, reset_at: right_now, approved_on: right_now) }
795-
let!(:other_matching_product) { Product.create!(title: title, admin: false, document: { nested: { are: "0" } }) }
793+
let!(:ignored_product) { Product.create!(title: "bar", rankings: [2]) }
794+
let!(:matching_product) do
795+
Product.create!(
796+
title: title,
797+
external_id: 3,
798+
admin: true,
799+
a_big_number: 23,
800+
reviewed_at: right_now,
801+
reset_at: right_now,
802+
approved_on: right_now,
803+
rankings: [1, 3]
804+
)
805+
end
806+
807+
let!(:other_matching_product) do
808+
Product.create!(
809+
title: title,
810+
admin: false,
811+
rankings: [3],
812+
document: { nested: { are: "0" } }
813+
)
814+
end
796815

797816
describe "#<jsonb_attribute_name>_contains" do
798817
it "is a collection of records that match the query" do
@@ -1007,6 +1026,13 @@
10071026
end
10081027
end
10091028
end
1029+
1030+
describe "#<array_field>_contains" do
1031+
it "is all records that contain the argument" do
1032+
expect(Product.rankings_contains(3)).to match_array([matching_product, other_matching_product])
1033+
expect(Product.rankings_contains(1)).to match_array([matching_product])
1034+
end
1035+
end
10101036
end
10111037

10121038
context "ActionDispatch clean up" do

0 commit comments

Comments
 (0)