fix undefined method eq for Arel::Nodes::Equality by deep call left

This commit is contained in:
Qian Chen 2018-06-21 15:50:11 +08:00
parent 322a014cd4
commit 2cc9b919c3
3 changed files with 60 additions and 1 deletions

View File

@ -163,7 +163,7 @@ module Ransack
def build_correlated_subquery(association)
join_constraints = extract_joins(association)
join_root = join_constraints.shift
correlated_key = join_root.right.expr.left
correlated_key = extract_correlated_key(join_root)
subquery = Arel::SelectManager.new(association.base_klass)
subquery.from(join_root.left)
subquery.project(correlated_key)
@ -179,6 +179,18 @@ module Ransack
private
def extract_correlated_key(join_root)
correlated_key = join_root.right.expr.left
if correlated_key.is_a? Arel::Nodes::And
correlated_key = correlated_key.left.left
elsif correlated_key.is_a? Arel::Nodes::Equality
correlated_key = correlated_key.left
else
correlated_key
end
end
def get_parent_and_attribute_name(str, parent = @base)
attr_name = nil

View File

@ -40,6 +40,47 @@ module Ransack
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
end
describe 'sharing context across searches' do
let(:shared_context) { Context.for(Person) }

View File

@ -29,6 +29,8 @@ class Person < ActiveRecord::Base
belongs_to :parent, class_name: 'Person', foreign_key: :parent_id
has_many :children, class_name: 'Person', foreign_key: :parent_id
has_many :articles
has_many :story_articles
has_many :published_articles, ->{ where(published: true) },
class_name: "Article"
has_many :comments
@ -136,6 +138,9 @@ class Article < ActiveRecord::Base
default_scope { where("'default_scope' = 'default_scope'") }
end
class StoryArticle < Article
end
class Recommendation < ActiveRecord::Base
belongs_to :person
belongs_to :target_person, class_name: 'Person'
@ -194,6 +199,7 @@ module Schema
t.string :title
t.text :subject_header
t.text :body
t.string :type
t.boolean :published, default: true
end