Avoid overwriting association conditions with default scope
When joining ransackable associations in Rails 3, preserve both: * association default_scope * association conditions Combining the stashed JoinAssociation with a separate string join for the "AND" conditions looks like a hack, but there is no cleaner way to extract the default_scope conditions with correct table aliases and merge them back into the association since ActiveRecord rebuilds its own join parts when generating the query.
This commit is contained in:
parent
d5d1cfaacf
commit
9f778e8c6c
|
@ -182,23 +182,19 @@ module Ransack
|
|||
:build, Polyamorous::Join.new(name, @join_type, klass), parent
|
||||
)
|
||||
found_association = @join_dependency.join_associations.last
|
||||
apply_default_conditions(found_association)
|
||||
|
||||
default_conditions = found_association.active_record.scoped.arel.constraints
|
||||
if default_conditions.any?
|
||||
and_default_conditions = "AND #{default_conditions.reduce(&:and).to_sql}"
|
||||
end
|
||||
|
||||
# Leverage the stashed association functionality in AR
|
||||
@object = @object.joins(found_association)
|
||||
@object = @object.joins(found_association).joins(and_default_conditions)
|
||||
end
|
||||
|
||||
found_association
|
||||
end
|
||||
|
||||
def apply_default_conditions(join_association)
|
||||
reflection = join_association.reflection
|
||||
default_scope = join_association.active_record.scoped
|
||||
default_conditions = default_scope.arel.where_clauses
|
||||
if default_conditions.any?
|
||||
reflection.options[:conditions] = default_conditions
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -90,8 +90,8 @@ module Ransack
|
|||
#
|
||||
def join_sources
|
||||
base = Arel::SelectManager.new(@object.engine, @object.table)
|
||||
joins = @object.joins_values
|
||||
joins.each do |assoc|
|
||||
@object.joins_values.each do |assoc|
|
||||
next unless assoc.is_a?(JoinDependency::JoinAssociation)
|
||||
assoc.join_to(base)
|
||||
end
|
||||
base.join_sources
|
||||
|
@ -151,7 +151,7 @@ module Ransack
|
|||
Constants::STRING_JOIN
|
||||
when Hash, Symbol, Array
|
||||
Constants::ASSOCIATION_JOIN
|
||||
when ::ActiveRecord::Associations::JoinDependency::JoinAssociation
|
||||
when JoinDependency::JoinAssociation
|
||||
Constants::STASHED_JOIN
|
||||
when Arel::Nodes::Join
|
||||
Constants::JOIN_NODE
|
||||
|
@ -196,23 +196,19 @@ module Ransack
|
|||
:build, Polyamorous::Join.new(name, @join_type, klass), parent
|
||||
)
|
||||
found_association = @join_dependency.join_associations.last
|
||||
apply_default_conditions(found_association)
|
||||
|
||||
default_conditions = found_association.active_record.scoped.arel.constraints
|
||||
if default_conditions.any?
|
||||
and_default_conditions = "AND #{default_conditions.reduce(&:and).to_sql}"
|
||||
end
|
||||
|
||||
# Leverage the stashed association functionality in AR
|
||||
@object = @object.joins(found_association)
|
||||
@object = @object.joins(found_association).joins(and_default_conditions)
|
||||
end
|
||||
|
||||
found_association
|
||||
end
|
||||
|
||||
def apply_default_conditions(join_association)
|
||||
reflection = join_association.reflection
|
||||
default_scope = join_association.active_record.scoped
|
||||
default_conditions = default_scope.arel.where_clauses
|
||||
if default_conditions.any?
|
||||
reflection.options[:conditions] = default_conditions
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -93,9 +93,10 @@ module Ransack
|
|||
expect(condition.value).to eq 'Ernie'
|
||||
end
|
||||
|
||||
it 'preserves default scope conditions for associations' do
|
||||
search = Search.new(Person, articles_title_eq: 'Test')
|
||||
it 'preserves default scope and conditions for associations' do
|
||||
search = Search.new(Person, published_articles_title_eq: 'Test')
|
||||
expect(search.result.to_sql).to include 'default_scope'
|
||||
expect(search.result.to_sql).to include 'published'
|
||||
end
|
||||
|
||||
it 'discards empty conditions' do
|
||||
|
|
|
@ -33,6 +33,7 @@ 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 :published_articles, :class_name => 'Article', :conditions => {published: true}
|
||||
has_many :comments
|
||||
has_many :authored_article_comments, :through => :articles,
|
||||
:source => :comments, :foreign_key => :person_id
|
||||
|
@ -171,6 +172,7 @@ module Schema
|
|||
t.string :title
|
||||
t.text :subject_header
|
||||
t.text :body
|
||||
t.boolean :published, default: true
|
||||
end
|
||||
|
||||
create_table :comments, :force => true do |t|
|
||||
|
|
Loading…
Reference in New Issue