From e0fae505849827f186e945dba93f704c278b9c3e Mon Sep 17 00:00:00 2001 From: Bilal Date: Wed, 29 Apr 2020 07:22:03 +0200 Subject: [PATCH] add new tables and models for join through association --- spec/lib/pg_searchable_new_spec.rb | 74 +++++++++++++++++++++++++++--- spec/schema.rb | 15 ++++++ spec/support/models.rb | 18 ++++++++ 3 files changed, 101 insertions(+), 6 deletions(-) diff --git a/spec/lib/pg_searchable_new_spec.rb b/spec/lib/pg_searchable_new_spec.rb index 1f2c8cc..4084fc4 100644 --- a/spec/lib/pg_searchable_new_spec.rb +++ b/spec/lib/pg_searchable_new_spec.rb @@ -161,9 +161,9 @@ describe PgSearchable do describe 'searching in model with has_many association' do before do records = DynamicModelWithTagValues.create [{ name: 'something', value: 'amazing' }, - { name: 'new record', value: 'not so amazing' }, - { name: 'last one', value: 'no value' }, - { name: 'really last one', value: 'no value' }] + { name: 'new record', value: 'not so amazing' }, + { name: 'last one', value: 'no value' }, + { name: 'really last one', value: 'no value' }] Tag.create [{ taggable: records[0], value: 'red', custom_attribute: 'rose' }, { taggable: records[0], value: 'green', custom_attribute: 'garden' }, @@ -242,9 +242,9 @@ describe PgSearchable do describe 'searching in model with multiple has_many associations' do before do records = DynamicModelWithTagAndCategories.create [{ name: 'something', value: 'amazing' }, - { name: 'new record', value: 'not so amazing' }, - { name: 'last one', value: 'no value' }, - { name: 'really last one', value: 'no value' }] + { name: 'new record', value: 'not so amazing' }, + { name: 'last one', value: 'no value' }, + { name: 'really last one', value: 'no value' }] Tag.create [{ taggable: records[0], value: 'red', custom_attribute: 'rose' }, { taggable: records[0], value: 'green', custom_attribute: 'garden' }, @@ -285,6 +285,68 @@ describe PgSearchable do expect(DynamicModelWithTagAndCategories.scope_search('(tag:- and not tag:12) or (value:"amazing" and not value:"not") or (category:unknown or category:math)')).to contain_exactly(records[0], records[2], records[3]) end end + + describe 'joins with through association' do + let(:players) { Player.all } + + before do + players = Player.create([{ name: 'first', value: 'downtown' }, + { name: 'redliner', value: 'uptown' }, + { name: 'flying', value: 'eagle' }, + { name: 'blue', value: 'marine' }]) + + + ptags = Ptag.create [{ value: 'e-ink' }, + { value: 'black&white' }, + { value: 'rich' }, + { value: 'grayscale' }, + { value: 'LED' }] + + players[0].ptags << ptags[0..1] + players[1].ptags << ptags[0..2] + players[2].ptags << ptags[2..3] + players[3].ptags << ptags[4] + end + + it 'can search in default column of model with through association' do + expect(Player.scope_search('l and not y and not blue')).to contain_exactly(players[1]) + end + + it 'can search in referenced column associated with through relation - simple search' do + expect(Player.scope_search('tag:e-ink')).to contain_exactly(players[0], players[1]) + end + + it 'can search in referenced column associated with through relaction - simple search with OR operator' do + expect(Player.scope_search('tag:e-ink OR tag:rich')).to contain_exactly(players[0], players[1], players[2]) + end + + it 'can search in referenced column associated with through relaction - simple search with AND operator' do + expect(Player.scope_search('tag:e-ink AND tag:rich')).to contain_exactly(players[1]) + end + + it 'can search in referenced column associated with through relaction - simple search with NOT operator' do + puts "===========" + puts Player.scope_search('NOT tag:e-ink').inspect + puts "===============" + expect(Player.scope_search('NOT tag:e-ink')).to contain_exactly(players[2], players[3]) + end + + it 'can search in referenced column associated with through relaction - mixed search terms with OR' do + expect(Player.scope_search('tag:e-ink OR blue')).to contain_exactly(players[0], players[1], players[3]) + end + + it 'can search in referenced column associated with through relaction - mixed search terms with AND' do + expect(Player.scope_search('tag:e-ink AND first')).to contain_exactly(players[0]) + end + + it 'can search in referenced column associated with through relaction - mixed search terms with OR NOT' do + expect(Player.scope_search('tag:led OR NOT first')).to contain_exactly(players[1], players[2], players[3]) + end + + it 'can search in referenced column associated with through relaction - mixed search terms with AND NOT' do + expect(Player.scope_search('tag:e-ink AND NOT first')).to contain_exactly(players[1]) + end + end end end end diff --git a/spec/schema.rb b/spec/schema.rb index ae3e2f2..8c20819 100644 --- a/spec/schema.rb +++ b/spec/schema.rb @@ -44,4 +44,19 @@ ActiveRecord::Schema.define do t.string :name t.timestamps null: false end + + create_table :players, force: true do |t| + t.string :name + t.string :value + t.timestamps null: false + end + + create_table :ptags, force: true do |t| + t.string :value + end + + create_table :taggings, force: true do |t| + t.belongs_to :player + t.belongs_to :ptag + end end diff --git a/spec/support/models.rb b/spec/support/models.rb index 5dd6f36..721b80f 100755 --- a/spec/support/models.rb +++ b/spec/support/models.rb @@ -129,3 +129,21 @@ class Category < ActiveRecord::Base has_many :tags belongs_to :categoriable, polymorphic: true end + +class Player < ActiveRecord::Base + include PgSearchable + pg_search fields: %i[players.id players.name players.value], default_fields: [:name], fields_mappings: { tag: 'ptags.value' }, joins: [:ptags] + has_many :taggings + has_many :ptags, through: :taggings +end + +class Ptag < ActiveRecord::Base + self.table_name = :ptags + has_many :taggings + has_many :players, through: :taggings +end + +class Tagging < ActiveRecord::Base + belongs_to :player + belongs_to :ptag +end \ No newline at end of file