From 36119d8e3ef41564f131881df7190bc9e7d36615 Mon Sep 17 00:00:00 2001 From: Sergio Cambra Date: Mon, 7 Jul 2025 21:08:22 +0200 Subject: [PATCH] support using a different grammar with LogicalQueryParser.search --- lib/logical_query_parser.rb | 7 +++-- .../nodes/active_record_spec.rb | 30 +++++++++++++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/lib/logical_query_parser.rb b/lib/logical_query_parser.rb index d7afdae..387847e 100644 --- a/lib/logical_query_parser.rb +++ b/lib/logical_query_parser.rb @@ -14,10 +14,11 @@ def new LogicalQueryParserParser.new end - def search(query, relations, *options) + def search(query, relations, *args, parser: new, **options) relations = relations.all if relations.respond_to?(:all) - assoc = resolve_assocs(relations.klass, *options) - sql = new.parse(query).to_sql(model: relations.klass, columns: assoc.column_mapping) + args << options if options.any? + assoc = resolve_assocs(relations.klass, *args) + sql = parser.parse(query).to_sql(model: relations.klass, columns: assoc.column_mapping) relations.joins(assoc.structure).where(sql) end diff --git a/spec/logical_query_parser/nodes/active_record_spec.rb b/spec/logical_query_parser/nodes/active_record_spec.rb index ce8389e..9e902b1 100644 --- a/spec/logical_query_parser/nodes/active_record_spec.rb +++ b/spec/logical_query_parser/nodes/active_record_spec.rb @@ -213,4 +213,34 @@ expect(relations.to_a).not_to be_nil end end + + context 'search with parser' do + it 'searches' do + relations = LogicalQueryParser.search("aa AND bb", Doc, :title, :body, parser: LogicalQueryParserParser.new) + debug(relations.to_sql) + expect(relations.to_sql).to match sequence %W|( ( title aa OR body aa ) AND ( title bb OR body bb )| + expect(relations.to_a).not_to be_nil + end + + it 'searches one association' do + relations = LogicalQueryParser.search("aa AND bb", Doc, :title, { tags: :name }, parser: LogicalQueryParserParser.new) + debug(relations.to_sql) + expect(relations.to_sql).to match sequence %W|( ( title aa OR tags name aa ) AND ( title bb OR tags name bb )| + expect(relations.to_a).not_to be_nil + end + + it 'searches nested association' do + relations = LogicalQueryParser.search("aa AND bb", Doc, :title, tags: [:name, users: :name], parser: LogicalQueryParserParser.new) + debug(relations.to_sql) + expect(relations.to_sql).to match sequence %W|( ( ( title aa OR tags name aa ) OR users name aa ) AND ( ( title bb OR tags name bb ) OR users name bb )| + expect(relations.to_a).not_to be_nil + end + + it 'searches nested association with array' do + relations = LogicalQueryParser.search("aa AND bb", Doc, [:title, tags: [:name, users: :name]], parser: LogicalQueryParserParser.new) + debug(relations.to_sql) + expect(relations.to_sql).to match sequence %W|( ( ( title aa OR tags name aa ) OR users name aa ) AND ( ( title bb OR tags name bb ) OR users name bb )| + expect(relations.to_a).not_to be_nil + end + end end