148 lines
5.9 KiB
Ruby
148 lines
5.9 KiB
Ruby
require 'spec_helper'
|
|
|
|
module Ransack
|
|
module Adapters
|
|
module ActiveRecord
|
|
version = ::ActiveRecord::VERSION
|
|
AR_version = "#{version::MAJOR}.#{version::MINOR}"
|
|
|
|
describe Context do
|
|
subject { Context.new(Person) }
|
|
|
|
it 'has an Active Record alias tracker method' do
|
|
expect(subject.alias_tracker)
|
|
.to be_an ::ActiveRecord::Associations::AliasTracker
|
|
end
|
|
|
|
describe '#relation_for' do
|
|
it 'returns relation for given object' do
|
|
expect(subject.object).to be_an ::ActiveRecord::Relation
|
|
end
|
|
end
|
|
|
|
describe '#evaluate' do
|
|
it 'evaluates search objects' do
|
|
s = Search.new(Person, name_eq: 'Joe Blow')
|
|
result = subject.evaluate(s)
|
|
|
|
expect(result).to be_an ::ActiveRecord::Relation
|
|
expect(result.to_sql)
|
|
.to match /#{quote_column_name("name")} = 'Joe Blow'/
|
|
end
|
|
|
|
it 'SELECTs DISTINCT when distinct: true' do
|
|
s = Search.new(Person, name_eq: 'Joe Blow')
|
|
result = subject.evaluate(s, distinct: true)
|
|
|
|
expect(result).to be_an ::ActiveRecord::Relation
|
|
expect(result.to_sql).to match /SELECT DISTINCT/
|
|
end
|
|
end
|
|
|
|
describe '#build_correlated_subquery' do
|
|
it 'build correlated subquery for Root STI model' do
|
|
search = Search.new(Person, { articles_title_not_eq: 'some_title' }, context: subject)
|
|
attribute = search.conditions.first.attributes.first
|
|
constraints = subject.build_correlated_subquery(attribute.parent).constraints
|
|
constraint = constraints.first
|
|
|
|
expect(constraints.length).to eql 1
|
|
expect(constraint.left.name).to eql 'person_id'
|
|
expect(constraint.left.relation.name).to eql 'articles'
|
|
expect(constraint.right.name).to eql 'id'
|
|
expect(constraint.right.relation.name).to eql 'people'
|
|
end
|
|
|
|
it 'build correlated subquery for Child STI model when predicate is not_eq' do
|
|
search = Search.new(Person, { story_articles_title_not_eq: 'some_title' }, context: subject)
|
|
attribute = search.conditions.first.attributes.first
|
|
constraints = subject.build_correlated_subquery(attribute.parent).constraints
|
|
constraint = constraints.first
|
|
|
|
expect(constraints.length).to eql 1
|
|
expect(constraint.left.relation.name).to eql 'articles'
|
|
expect(constraint.left.name).to eql 'person_id'
|
|
expect(constraint.right.relation.name).to eql 'people'
|
|
expect(constraint.right.name).to eql 'id'
|
|
end
|
|
|
|
it 'build correlated subquery for Child STI model when predicate is eq' do
|
|
search = Search.new(Person, { story_articles_title_not_eq: 'some_title' }, context: subject)
|
|
attribute = search.conditions.first.attributes.first
|
|
constraints = subject.build_correlated_subquery(attribute.parent).constraints
|
|
constraint = constraints.first
|
|
|
|
expect(constraints.length).to eql 1
|
|
expect(constraint.left.relation.name).to eql 'articles'
|
|
expect(constraint.left.name).to eql 'person_id'
|
|
expect(constraint.right.relation.name).to eql 'people'
|
|
expect(constraint.right.name).to eql 'id'
|
|
end
|
|
|
|
it 'build correlated subquery for multiple conditions (default scope)' do
|
|
search = Search.new(Person, { comments_body_not_eq: 'some_title' })
|
|
|
|
# Was
|
|
# SELECT "people".* FROM "people" WHERE "people"."id" NOT IN (
|
|
# SELECT "comments"."disabled" FROM "comments"
|
|
# WHERE "comments"."disabled" = "people"."id"
|
|
# AND NOT ("comments"."body" != 'some_title')
|
|
# ) ORDER BY "people"."id" DESC
|
|
# Should Be
|
|
# SELECT "people".* FROM "people" WHERE "people"."id" NOT IN (
|
|
# SELECT "comments"."person_id" FROM "comments"
|
|
# WHERE "comments"."person_id" = "people"."id"
|
|
# AND NOT ("comments"."body" != 'some_title')
|
|
# ) ORDER BY "people"."id" DESC
|
|
|
|
expect(search.result.to_sql).to match /.comments.\..person_id. = .people.\..id./
|
|
end
|
|
end
|
|
|
|
describe 'sharing context across searches' do
|
|
let(:shared_context) { Context.for(Person) }
|
|
|
|
before do
|
|
Search.new(Person, { parent_name_eq: 'A' },
|
|
context: shared_context)
|
|
Search.new(Person, { children_name_eq: 'B' },
|
|
context: shared_context)
|
|
end
|
|
|
|
describe '#join_sources' do
|
|
it 'returns dependent arel join nodes for all searches run against
|
|
the context' do
|
|
parents, children = shared_context.join_sources
|
|
expect(children.left.name).to eq "children_people"
|
|
expect(parents.left.name).to eq "parents_people"
|
|
end
|
|
|
|
it 'can be rejoined to execute a valid query' do
|
|
parents, children = shared_context.join_sources
|
|
|
|
expect { Person.joins(parents).joins(children).to_a }
|
|
.to_not raise_error
|
|
end
|
|
end
|
|
end
|
|
|
|
it 'contextualizes strings to attributes' do
|
|
attribute = subject.contextualize 'children_children_parent_name'
|
|
expect(attribute).to be_a Arel::Attributes::Attribute
|
|
expect(attribute.name.to_s).to eq 'name'
|
|
expect(attribute.relation.table_alias).to eq 'parents_people'
|
|
end
|
|
|
|
it 'builds new associations if not yet built' do
|
|
attribute = subject.contextualize 'children_articles_title'
|
|
expect(attribute).to be_a Arel::Attributes::Attribute
|
|
expect(attribute.name.to_s).to eq 'title'
|
|
expect(attribute.relation.name).to eq 'articles'
|
|
expect(attribute.relation.table_alias).to be_nil
|
|
end
|
|
|
|
end
|
|
end
|
|
end
|
|
end
|