Code cleanup

This commit is contained in:
jonatack 2013-12-15 13:30:27 +01:00
parent 81e9406c6d
commit 1e24b60906
8 changed files with 135 additions and 62 deletions

View File

@ -132,9 +132,15 @@ module Arel
end
def visit_Arel_Nodes_NamedFunction o
"#{o.name}(#{o.distinct ? 'DISTINCT ' : ''}#{o.expressions.map { |x|
visit x
}.join(', ')})#{o.alias ? " AS #{visit o.alias}" : ''}"
"#{
o.name
}(#{
o.distinct ? 'DISTINCT ' : ''
}#{
o.expressions.map { |x| visit x }.join(', ')
})#{
o.alias ? " AS #{visit o.alias}" : ''
}"
end
def visit_Arel_Nodes_And o
@ -146,13 +152,17 @@ module Arel
end
def visit_Arel_Nodes_Values o
"VALUES (#{o.expressions.zip(o.columns).map { |value, attr|
"VALUES (#{
o.expressions.zip(o.columns)
.map { |value, attr|
if Nodes::SqlLiteral === value
visit_Arel_Nodes_SqlLiteral value
else
quote(value, attr && column_for(attr))
end
}.join ', '})"
}
.join ', '
})"
end
end
end

View File

@ -26,9 +26,11 @@ module Ransack
viz = Visitor.new
relation = @object.where(viz.accept(search.base))
if search.sorts.any?
relation = relation.except(:order).reorder(viz.accept(search.sorts))
relation = relation.except(:order)
.reorder(viz.accept(search.sorts))
end
opts[:distinct] ? relation.select("DISTINCT #{@klass.quoted_table_name}.*") : relation
opts[:distinct] ?
relation.select("DISTINCT #{@klass.quoted_table_name}.*") : relation
end
def attribute_method?(str, klass = @klass)
@ -39,10 +41,15 @@ module Ransack
elsif (segments = str.split(/_/)).size > 1
remainder = []
found_assoc = nil
while !found_assoc && remainder.unshift(segments.pop) && segments.size > 0 do
assoc, poly_class = unpolymorphize_association(segments.join('_'))
while !found_assoc && remainder.unshift(segments.pop) &&
segments.size > 0 do
assoc, poly_class = unpolymorphize_association(
segments.join('_')
)
if found_assoc = get_association(assoc, klass)
exists = attribute_method?(remainder.join('_'), poly_class || found_assoc.klass)
exists = attribute_method?(
remainder.join('_'), poly_class || found_assoc.klass
)
end
end
end
@ -56,7 +63,9 @@ module Ransack
def type_for(attr)
return nil unless attr && attr.valid?
klassify(attr.parent).columns_hash[attr.arel_attribute.name.to_s].type
klassify(attr.parent)
.columns_hash[attr.arel_attribute.name.to_s]
.type
end
private
@ -69,15 +78,19 @@ module Ransack
elsif (segments = str.split(/_/)).size > 1
remainder = []
found_assoc = nil
while remainder.unshift(segments.pop) && segments.size > 0 && !found_assoc do
while remainder.unshift(segments.pop) && segments.size > 0 &&
!found_assoc do
assoc, klass = unpolymorphize_association(segments.join('_'))
if found_assoc = get_association(assoc, parent)
join = build_or_find_association(found_assoc.name, parent, klass)
parent, attr_name = get_parent_and_attribute_name(remainder.join('_'), join)
join = build_or_find_association(
found_assoc.name, parent, klass
)
parent, attr_name = get_parent_and_attribute_name(
remainder.join('_'), join
)
end
end
end
[parent, attr_name]
end
@ -114,9 +127,9 @@ module Ransack
association_joins = buckets['association_join'] || []
stashed_association_joins = buckets['stashed_join'] || []
join_nodes = buckets['join_node'] || []
string_joins = (buckets['string_join'] || []).map { |x|
x.strip
}.uniq
string_joins = (buckets['string_join'] || [])
.map { |x| x.strip }
.uniq
join_list = relation.send :custom_join_sql, (string_joins + join_nodes)
@ -134,13 +147,16 @@ module Ransack
end
def build_or_find_association(name, parent = @base, klass = nil)
found_association = @join_dependency.join_associations.detect do |assoc|
found_association = @join_dependency.join_associations
.detect do |assoc|
assoc.reflection.name == name &&
assoc.parent == parent &&
(!klass || assoc.reflection.klass == klass)
end
unless found_association
@join_dependency.send(:build, Polyamorous::Join.new(name, @join_type, klass), parent)
@join_dependency.send(
:build, Polyamorous::Join.new(name, @join_type, klass), parent
)
found_association = @join_dependency.join_associations.last
# Leverage the stashed association functionality in AR
@object = @object.joins(found_association)

View File

@ -47,7 +47,8 @@ module Ransack
it 'can be accessed through associations' do
s = Person.search(:children_reversed_name_eq => 'htimS cirA')
s.result.to_sql.should match /#{quote_table_name("children_people")}.#{quote_column_name("name")} = 'Aric Smith'/
s.result.to_sql.should match /#{quote_table_name("children_people")
}.#{quote_column_name("name")} = 'Aric Smith'/
end
it 'allows an "attribute" to be an InfixOperation' do
@ -78,43 +79,62 @@ module Ransack
end
it 'allows sort by "only_sort" field' do
s = Person.search("s"=>{"0"=>{"dir"=>"asc", "name"=>"only_sort"}})
s.result.to_sql.should match /ORDER BY #{quote_table_name("people")}.#{quote_column_name("only_sort")} ASC/
s = Person.search(
"s" => { "0"=> { "dir" => "asc", "name" => "only_sort" } }
)
s.result.to_sql.should match /ORDER BY #{quote_table_name("people")
}.#{quote_column_name("only_sort")} ASC/
end
it "doesn't sort by 'only_search' field" do
s = Person.search("s"=>{"0"=>{"dir"=>"asc", "name"=>"only_search"}})
s.result.to_sql.should_not match /ORDER BY #{quote_table_name("people")}.#{quote_column_name("only_search")} ASC/
s = Person.search(
"s" => { "0" => { "dir" => "asc", "name" => "only_search" } }
)
s.result.to_sql.should_not match /ORDER BY #{quote_table_name("people")
}.#{quote_column_name("only_search")} ASC/
end
it 'allows search by "only_search" field' do
s = Person.search(:only_search_eq => 'htimS cirA')
s.result.to_sql.should match /WHERE #{quote_table_name("people")}.#{quote_column_name("only_search")} = 'htimS cirA'/
s.result.to_sql.should match /WHERE #{quote_table_name("people")
}.#{quote_column_name("only_search")} = 'htimS cirA'/
end
it "can't be searched by 'only_sort'" do
s = Person.search(:only_sort_eq => 'htimS cirA')
s.result.to_sql.should_not match /WHERE #{quote_table_name("people")}.#{quote_column_name("only_sort")} = 'htimS cirA'/
s.result.to_sql.should_not match /WHERE #{quote_table_name("people")
}.#{quote_column_name("only_sort")} = 'htimS cirA'/
end
it 'allows sort by "only_admin" field, if auth_object: :admin' do
s = Person.search({"s"=>{"0"=>{"dir"=>"asc", "name"=>"only_admin"}}}, {auth_object: :admin})
s.result.to_sql.should match /ORDER BY #{quote_table_name("people")}.#{quote_column_name("only_admin")} ASC/
s = Person.search(
{ "s" => { "0" => { "dir" => "asc", "name" => "only_admin" } } },
{ auth_object: :admin }
)
s.result.to_sql.should match /ORDER BY #{quote_table_name("people")
}.#{quote_column_name("only_admin")} ASC/
end
it "doesn't sort by 'only_admin' field, if auth_object: nil" do
s = Person.search("s"=>{"0"=>{"dir"=>"asc", "name"=>"only_admin"}})
s.result.to_sql.should_not match /ORDER BY #{quote_table_name("people")}.#{quote_column_name("only_admin")} ASC/
s = Person.search(
"s" => { "0" => { "dir" => "asc", "name" => "only_admin" } }
)
s.result.to_sql.should_not match /ORDER BY
#{quote_table_name("people")}.#{quote_column_name("only_admin")} ASC/
end
it 'allows search by "only_admin" field, if auth_object: :admin' do
s = Person.search({:only_admin_eq => 'htimS cirA'}, {auth_object: :admin})
s.result.to_sql.should match /WHERE #{quote_table_name("people")}.#{quote_column_name("only_admin")} = 'htimS cirA'/
s = Person.search(
{ :only_admin_eq => 'htimS cirA'}, { auth_object: :admin }
)
s.result.to_sql.should match /WHERE #{quote_table_name("people")
}.#{quote_column_name("only_admin")} = 'htimS cirA'/
end
it "can't be searched by 'only_admin', if auth_object: nil" do
s = Person.search(:only_admin_eq => 'htimS cirA')
s.result.to_sql.should_not match /WHERE #{quote_table_name("people")}.#{quote_column_name("only_admin")} = 'htimS cirA'/
s.result.to_sql.should_not match /WHERE #{quote_table_name("people")
}.#{quote_column_name("only_admin")} = 'htimS cirA'/
end
end

View File

@ -18,7 +18,8 @@ module Ransack
result = subject.evaluate(search)
result.should be_an ::ActiveRecord::Relation
result.to_sql.should match /#{quote_column_name("name")} = 'Joe Blow'/
result.to_sql.should match /#{
quote_column_name("name")} = 'Joe Blow'/
end
it 'SELECTs DISTINCT when :distinct => true' do

View File

@ -20,12 +20,17 @@ module Ransack
it 'avoids creating compound predicates if :compounds => false' do
Ransack.configure do |config|
config.add_predicate :test_predicate_without_compound, :compounds => false
config.add_predicate(
:test_predicate_without_compound,
:compounds => false
)
end
Ransack.predicates.should have_key 'test_predicate_without_compound'
Ransack.predicates.should_not have_key 'test_predicate_without_compound_any'
Ransack.predicates.should_not have_key 'test_predicate_without_compound_all'
Ransack.predicates
.should have_key 'test_predicate_without_compound'
Ransack.predicates
.should_not have_key 'test_predicate_without_compound_any'
Ransack.predicates
.should_not have_key 'test_predicate_without_compound_all'
end
it 'should have default value for search key' do
@ -48,7 +53,11 @@ module Ransack
it 'adds predicates that take arrays, overriding compounds' do
Ransack.configure do |config|
config.add_predicate :test_array_predicate, :wants_array => true, :compounds => true
config.add_predicate(
:test_array_predicate,
:wants_array => true,
:compounds => true
)
end
Ransack.predicates['test_array_predicate'].wants_array.should eq true

View File

@ -91,8 +91,8 @@ module Ransack
end
it 'returns ransackable attributes for associations with :associations' do
attributes = Person.ransackable_attributes + Article.
ransackable_attributes.map { |a| "articles_#{a}" }
attributes = Person.ransackable_attributes +
Article.ransackable_attributes.map { |a| "articles_#{a}" }
html = @f.attribute_select(:associations => ['articles'])
html.split(/\n/).should have(attributes.size).lines
attributes.each do |attribute|

View File

@ -22,14 +22,17 @@ module Ransack
describe 'eq' do
it 'generates an equality condition for boolean true' do
@s.awesome_eq = true
field = "#{quote_table_name("people")}.#{quote_column_name("awesome")}"
@s.result.to_sql.should match /#{field} = #{ActiveRecord::Base.connection.quoted_true}/
field = "#{quote_table_name("people")}.#{
quote_column_name("awesome")}"
@s.result.to_sql.should match /#{field} = #{
ActiveRecord::Base.connection.quoted_true}/
end
it 'generates an equality condition for boolean false' do
@s.awesome_eq = false
field = "#{quote_table_name("people")}.#{quote_column_name("awesome")}"
@s.result.to_sql.should match /#{field} = #{ActiveRecord::Base.connection.quoted_false}/
@s.result.to_sql.should match /#{field} = #{
ActiveRecord::Base.connection.quoted_false}/
end
it 'does not generate a condition for nil' do

View File

@ -34,8 +34,8 @@ module Ransack
it 'creates Conditions for multiple polymorphic belongs_to association attributes' do
search = Search.new(Note,
:notable_of_Person_type_name_or_notable_of_Article_type_title_eq => 'Ernie')
condition = search.
base[:notable_of_Person_type_name_or_notable_of_Article_type_title_eq]
condition = search
.base[:notable_of_Person_type_name_or_notable_of_Article_type_title_eq]
condition.should be_a Nodes::Condition
condition.predicate.name.should eq 'eq'
condition.attributes.first.name.should eq 'notable_of_Person_type_name'
@ -68,8 +68,16 @@ module Ransack
it 'accepts "attributes" hashes for groupings' do
search = Search.new(Person,
:g => {
'0' => { :m => 'or', :name_eq => 'Ernie', :children_name_eq => 'Ernie' },
'1' => { :m => 'or', :name_eq => 'Bert', :children_name_eq => 'Bert' },
'0' => {
:m => 'or',
:name_eq => 'Ernie',
:children_name_eq => 'Ernie'
},
'1' => {
:m => 'or',
:name_eq => 'Bert',
:children_name_eq => 'Bert'
},
}
)
ors = search.groupings
@ -85,16 +93,14 @@ module Ransack
search = Search.new(Person,
:c => {
'0' => { :a => ['name'], :p => 'eq', :v => ['Ernie'] },
'1' => {
:a => ['children_name', 'parent_name'],
:p => 'eq', :v => ['Ernie'], :m => 'or'
}
}
'1' => { :a => ['children_name', 'parent_name'],
:p => 'eq', :v => ['Ernie'], :m => 'or' }
}
)
conditions = search.base.conditions
conditions.should have(2).items
conditions.map { |c| c.class }.
should eq [Nodes::Condition, Nodes::Condition]
conditions.map { |c| c.class }
.should eq [Nodes::Condition, Nodes::Condition]
end
it 'creates Conditions for custom predicates that take arrays' do
@ -117,8 +123,12 @@ module Ransack
end
describe '#result' do
let(:people_name_field) { "#{quote_table_name("people")}.#{quote_column_name("name")}" }
let(:children_people_name_field) { "#{quote_table_name("children_people")}.#{quote_column_name("name")}" }
let(:people_name_field) {
"#{quote_table_name("people")}.#{quote_column_name("name")}"
}
let(:children_people_name_field) {
"#{quote_table_name("children_people")}.#{quote_column_name("name")}"
}
it 'evaluates conditions contextually' do
search = Search.new(Person, :children_name_eq => 'Ernie')
search.result.should be_an ActiveRecord::Relation
@ -130,7 +140,8 @@ module Ransack
search = Search.new(Person, :children_name_or_name_eq => 'Ernie')
search.result.should be_an ActiveRecord::Relation
where = search.result.where_values.first
where.to_sql.should match /#{children_people_name_field} = 'Ernie' OR #{people_name_field} = 'Ernie'/
where.to_sql.should match /#{children_people_name_field
} = 'Ernie' OR #{people_name_field} = 'Ernie'/
end
it 'evaluates polymorphic belongs_to association conditions contextually' do
@ -153,7 +164,8 @@ module Ransack
where = search.result.where_values.first
where.to_sql.should match /#{children_people_name_field} = 'Ernie'/
where.to_sql.should match /#{people_name_field} = 'Ernie'/
where.to_sql.should match /#{quote_table_name("children_people_2")}.#{quote_column_name("name")} = 'Ernie'/
where.to_sql.should match /#{quote_table_name("children_people_2")
}.#{quote_column_name("name")} = 'Ernie'/
end
it 'evaluates arrays of groupings' do
@ -324,7 +336,9 @@ module Ransack
end
it 'allows chaining to access nested conditions' do
@s.groupings = [{ :m => 'or', :name_eq => 'Ernie', :children_name_eq => 'Ernie' }]
@s.groupings = [
{ :m => 'or', :name_eq => 'Ernie', :children_name_eq => 'Ernie' }
]
@s.groupings.first.children_name_eq.should eq 'Ernie'
end
end