Merge branch 'master' into bring-rails-3
Conflicts: .travis.yml Gemfile README.md lib/ransack/adapters/active_record/3.0/context.rb lib/ransack/adapters/active_record/3.1/context.rb lib/ransack/adapters/active_record/3.2/context.rb lib/ransack/adapters/active_record/base.rb lib/ransack/adapters/active_record/context.rb lib/ransack/constants.rb lib/ransack/context.rb lib/ransack/helpers/form_builder.rb lib/ransack/helpers/form_helper.rb lib/ransack/nodes/attribute.rb lib/ransack/nodes/condition.rb lib/ransack/nodes/grouping.rb lib/ransack/nodes/sort.rb lib/ransack/predicate.rb lib/ransack/translate.rb ransack.gemspec spec/blueprints/people.rb spec/ransack/adapters/active_record/base_spec.rb spec/ransack/adapters/active_record/context_spec.rb spec/ransack/configuration_spec.rb spec/ransack/dependencies_spec.rb spec/ransack/helpers/form_builder_spec.rb spec/ransack/helpers/form_helper_spec.rb spec/ransack/predicate_spec.rb spec/ransack/search_spec.rb spec/ransack/translate_spec.rb spec/support/schema.rb
This commit is contained in:
commit
b4973315e9
15
.travis.yml
15
.travis.yml
|
@ -9,12 +9,21 @@ rvm:
|
||||||
- 2.1.1
|
- 2.1.1
|
||||||
|
|
||||||
env:
|
env:
|
||||||
- RAILS=4-0-stable DB=sqlite3
|
|
||||||
- RAILS=4-0-stable DB=mysql
|
|
||||||
- RAILS=4-0-stable DB=postgres
|
|
||||||
- RAILS=4-1-stable DB=sqlite3
|
- RAILS=4-1-stable DB=sqlite3
|
||||||
- RAILS=4-1-stable DB=mysql
|
- RAILS=4-1-stable DB=mysql
|
||||||
- RAILS=4-1-stable DB=postgres
|
- RAILS=4-1-stable DB=postgres
|
||||||
|
- RAILS=4-0-stable DB=sqlite3
|
||||||
|
- RAILS=4-0-stable DB=mysql
|
||||||
|
- RAILS=4-0-stable DB=postgres
|
||||||
|
- RAILS=3-2-stable DB=sqlite
|
||||||
|
- RAILS=3-2-stable DB=mysql
|
||||||
|
- RAILS=3-2-stable DB=postgres
|
||||||
|
- RAILS=3-1-stable DB=sqlite
|
||||||
|
- RAILS=3-1-stable DB=mysql
|
||||||
|
- RAILS=3-1-stable DB=postgres
|
||||||
|
- RAILS=3-0-stable DB=sqlite
|
||||||
|
- RAILS=3-0-stable DB=mysql
|
||||||
|
- RAILS=3-0-stable DB=postgres
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
- mysql -e 'create database ransack collate utf8_general_ci;'
|
- mysql -e 'create database ransack collate utf8_general_ci;'
|
||||||
|
|
3
Gemfile
3
Gemfile
|
@ -27,4 +27,7 @@ else
|
||||||
gem 'activerecord'
|
gem 'activerecord'
|
||||||
gem 'actionpack'
|
gem 'actionpack'
|
||||||
end
|
end
|
||||||
|
if rails == '3-0-stable'
|
||||||
|
gem 'mysql2', '< 0.3'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -133,6 +133,15 @@ Once you've done so, you can make use of the helpers in Ransack::Helpers::FormBu
|
||||||
construct much more complex search forms, such as the one on the
|
construct much more complex search forms, such as the one on the
|
||||||
[demo page](http://ransack-demo.heroku.com) (source code [here](https://github.com/activerecord-hackery/ransack_demo)).
|
[demo page](http://ransack-demo.heroku.com) (source code [here](https://github.com/activerecord-hackery/ransack_demo)).
|
||||||
|
|
||||||
|
### Ransack #search method
|
||||||
|
|
||||||
|
Ransack will try to to make `#search` available in your models, but in the case that `#search` has already been defined, you can use `#ransack` instead. For example the following would be equivalent:
|
||||||
|
|
||||||
|
```
|
||||||
|
Article.search(params[:q])
|
||||||
|
Article.ransack(params[:q])
|
||||||
|
```
|
||||||
|
|
||||||
### has_many and belongs_to associations
|
### has_many and belongs_to associations
|
||||||
|
|
||||||
You can easily use Ransack to search in associated objects.
|
You can easily use Ransack to search in associated objects.
|
||||||
|
|
|
@ -25,4 +25,4 @@ require 'ransack/adapters/active_record' if defined?(::ActiveRecord::Base)
|
||||||
require 'ransack/helpers'
|
require 'ransack/helpers'
|
||||||
require 'action_controller'
|
require 'action_controller'
|
||||||
|
|
||||||
ActionController::Base.helper Ransack::Helpers::FormHelper
|
ActionController::Base.helper Ransack::Helpers::FormHelper
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
if Arel::Nodes::And < Arel::Nodes::Binary
|
if Arel::Nodes::And < Arel::Nodes::Binary
|
||||||
class Ransack::Visitor
|
class Ransack::Visitor
|
||||||
def visit_Ransack_Nodes_And(object)
|
def visit_Ransack_Nodes_And(object)
|
||||||
nodes = object.values.map {|o| accept(o)}.compact
|
nodes = object.values.map { |o| accept(o) }.compact
|
||||||
return nil unless nodes.size > 0
|
return nil unless nodes.size > 0
|
||||||
|
|
||||||
if nodes.size > 1
|
if nodes.size > 1
|
||||||
|
@ -132,9 +132,15 @@ module Arel
|
||||||
end
|
end
|
||||||
|
|
||||||
def visit_Arel_Nodes_NamedFunction o
|
def visit_Arel_Nodes_NamedFunction o
|
||||||
"#{o.name}(#{o.distinct ? 'DISTINCT ' : ''}#{o.expressions.map { |x|
|
"#{
|
||||||
visit x
|
o.name
|
||||||
}.join(', ')})#{o.alias ? " AS #{visit o.alias}" : ''}"
|
}(#{
|
||||||
|
o.distinct ? 'DISTINCT ' : ''
|
||||||
|
}#{
|
||||||
|
o.expressions.map { |x| visit x }.join(', ')
|
||||||
|
})#{
|
||||||
|
o.alias ? " AS #{visit o.alias}" : ''
|
||||||
|
}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def visit_Arel_Nodes_And o
|
def visit_Arel_Nodes_And o
|
||||||
|
@ -146,13 +152,17 @@ module Arel
|
||||||
end
|
end
|
||||||
|
|
||||||
def visit_Arel_Nodes_Values o
|
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
|
if Nodes::SqlLiteral === value
|
||||||
visit_Arel_Nodes_SqlLiteral value
|
visit_Arel_Nodes_SqlLiteral value
|
||||||
else
|
else
|
||||||
quote(value, attr && column_for(attr))
|
quote(value, attr && column_for(attr))
|
||||||
end
|
end
|
||||||
}.join ', '})"
|
}
|
||||||
|
.join ', '
|
||||||
|
})"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -11,6 +11,8 @@ module Ransack
|
||||||
JoinDependency = ::ActiveRecord::Associations::ClassMethods::JoinDependency
|
JoinDependency = ::ActiveRecord::Associations::ClassMethods::JoinDependency
|
||||||
JoinBase = JoinDependency::JoinBase
|
JoinBase = JoinDependency::JoinBase
|
||||||
|
|
||||||
|
# Redefine a few things for ActiveRecord 3.0.
|
||||||
|
|
||||||
def initialize(object, options = {})
|
def initialize(object, options = {})
|
||||||
super
|
super
|
||||||
@arel_visitor = Arel::Visitors.visitor_for @engine
|
@arel_visitor = Arel::Visitors.visitor_for @engine
|
||||||
|
@ -24,10 +26,11 @@ module Ransack
|
||||||
viz = Visitor.new
|
viz = Visitor.new
|
||||||
relation = @object.where(viz.accept(search.base))
|
relation = @object.where(viz.accept(search.base))
|
||||||
if search.sorts.any?
|
if search.sorts.any?
|
||||||
relation = relation.except(:order).reorder(viz.accept(search.sorts))
|
relation = relation.except(:order)
|
||||||
|
.reorder(viz.accept(search.sorts))
|
||||||
end
|
end
|
||||||
opts[:distinct] ? relation.select(
|
opts[:distinct] ?
|
||||||
"DISTINCT #{@klass.quoted_table_name}.*") : relation
|
relation.select("DISTINCT #{@klass.quoted_table_name}.*") : relation
|
||||||
end
|
end
|
||||||
|
|
||||||
def attribute_method?(str, klass = @klass)
|
def attribute_method?(str, klass = @klass)
|
||||||
|
@ -38,10 +41,15 @@ module Ransack
|
||||||
elsif (segments = str.split(/_/)).size > 1
|
elsif (segments = str.split(/_/)).size > 1
|
||||||
remainder = []
|
remainder = []
|
||||||
found_assoc = nil
|
found_assoc = nil
|
||||||
while !found_assoc && remainder.unshift(segments.pop) && segments.size > 0 do
|
while !found_assoc && remainder.unshift(segments.pop) &&
|
||||||
assoc, poly_class = unpolymorphize_association(segments.join('_'))
|
segments.size > 0 do
|
||||||
|
assoc, poly_class = unpolymorphize_association(
|
||||||
|
segments.join('_')
|
||||||
|
)
|
||||||
if found_assoc = get_association(assoc, klass)
|
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
|
end
|
||||||
end
|
end
|
||||||
|
@ -52,10 +60,12 @@ module Ransack
|
||||||
def table_for(parent)
|
def table_for(parent)
|
||||||
parent.table
|
parent.table
|
||||||
end
|
end
|
||||||
|
|
||||||
def type_for(attr)
|
def type_for(attr)
|
||||||
return nil unless attr && attr.valid?
|
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
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -68,22 +78,26 @@ module Ransack
|
||||||
elsif (segments = str.split(/_/)).size > 1
|
elsif (segments = str.split(/_/)).size > 1
|
||||||
remainder = []
|
remainder = []
|
||||||
found_assoc = nil
|
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('_'))
|
assoc, klass = unpolymorphize_association(segments.join('_'))
|
||||||
if found_assoc = get_association(assoc, parent)
|
if found_assoc = get_association(assoc, parent)
|
||||||
join = build_or_find_association(found_assoc.name, parent, klass)
|
join = build_or_find_association(
|
||||||
parent, attr_name = get_parent_and_attribute_name(remainder.join('_'), join)
|
found_assoc.name, parent, klass
|
||||||
|
)
|
||||||
|
parent, attr_name = get_parent_and_attribute_name(
|
||||||
|
remainder.join('_'), join
|
||||||
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
[parent, attr_name]
|
[parent, attr_name]
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_association(str, parent = @base)
|
def get_association(str, parent = @base)
|
||||||
klass = klassify parent
|
klass = klassify parent
|
||||||
ransackable_association?(str, klass) &&
|
ransackable_association?(str, klass) &&
|
||||||
klass.reflect_on_all_associations.detect {|a| a.name.to_s == str}
|
klass.reflect_on_all_associations.detect { |a| a.name.to_s == str }
|
||||||
end
|
end
|
||||||
|
|
||||||
def join_dependency(relation)
|
def join_dependency(relation)
|
||||||
|
@ -113,9 +127,9 @@ module Ransack
|
||||||
association_joins = buckets['association_join'] || []
|
association_joins = buckets['association_join'] || []
|
||||||
stashed_association_joins = buckets['stashed_join'] || []
|
stashed_association_joins = buckets['stashed_join'] || []
|
||||||
join_nodes = buckets['join_node'] || []
|
join_nodes = buckets['join_node'] || []
|
||||||
string_joins = (buckets['string_join'] || []).map { |x|
|
string_joins = (buckets['string_join'] || [])
|
||||||
x.strip
|
.map { |x| x.strip }
|
||||||
}.uniq
|
.uniq
|
||||||
|
|
||||||
join_list = relation.send :custom_join_sql, (string_joins + join_nodes)
|
join_list = relation.send :custom_join_sql, (string_joins + join_nodes)
|
||||||
|
|
||||||
|
@ -133,13 +147,16 @@ module Ransack
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_or_find_association(name, parent = @base, klass = nil)
|
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.reflection.name == name &&
|
||||||
assoc.parent == parent &&
|
assoc.parent == parent &&
|
||||||
(!klass || assoc.reflection.klass == klass)
|
(!klass || assoc.reflection.klass == klass)
|
||||||
end
|
end
|
||||||
unless found_association
|
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
|
found_association = @join_dependency.join_associations.last
|
||||||
# Leverage the stashed association functionality in AR
|
# Leverage the stashed association functionality in AR
|
||||||
@object = @object.joins(found_association)
|
@object = @object.joins(found_association)
|
||||||
|
|
|
@ -10,6 +10,8 @@ module Ransack
|
||||||
JoinDependency = ::ActiveRecord::Associations::JoinDependency
|
JoinDependency = ::ActiveRecord::Associations::JoinDependency
|
||||||
JoinPart = JoinDependency::JoinPart
|
JoinPart = JoinDependency::JoinPart
|
||||||
|
|
||||||
|
# Redefine a few things for ActiveRecord 3.1.
|
||||||
|
|
||||||
def initialize(object, options = {})
|
def initialize(object, options = {})
|
||||||
super
|
super
|
||||||
@arel_visitor = Arel::Visitors.visitor_for @engine
|
@arel_visitor = Arel::Visitors.visitor_for @engine
|
||||||
|
@ -23,10 +25,12 @@ module Ransack
|
||||||
viz = Visitor.new
|
viz = Visitor.new
|
||||||
relation = @object.where(viz.accept(search.base))
|
relation = @object.where(viz.accept(search.base))
|
||||||
if search.sorts.any?
|
if search.sorts.any?
|
||||||
relation = relation.except(:order).reorder(viz.accept(search.sorts))
|
relation = relation.except(:order)
|
||||||
|
.reorder(viz.accept(search.sorts))
|
||||||
end
|
end
|
||||||
opts[:distinct] ? relation.select(
|
opts[:distinct] ?
|
||||||
"DISTINCT #{@klass.quoted_table_name}.*") : relation
|
relation.select("DISTINCT #{@klass.quoted_table_name}.*") :
|
||||||
|
relation
|
||||||
end
|
end
|
||||||
|
|
||||||
def attribute_method?(str, klass = @klass)
|
def attribute_method?(str, klass = @klass)
|
||||||
|
@ -37,10 +41,15 @@ module Ransack
|
||||||
elsif (segments = str.split(/_/)).size > 1
|
elsif (segments = str.split(/_/)).size > 1
|
||||||
remainder = []
|
remainder = []
|
||||||
found_assoc = nil
|
found_assoc = nil
|
||||||
while !found_assoc && remainder.unshift(segments.pop) && segments.size > 0 do
|
while !found_assoc && remainder.unshift(segments.pop) &&
|
||||||
assoc, poly_class = unpolymorphize_association(segments.join('_'))
|
segments.size > 0 do
|
||||||
|
assoc, poly_class = unpolymorphize_association(
|
||||||
|
segments.join('_')
|
||||||
|
)
|
||||||
if found_assoc = get_association(assoc, klass)
|
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
|
end
|
||||||
end
|
end
|
||||||
|
@ -74,11 +83,16 @@ module Ransack
|
||||||
elsif (segments = str.split(/_/)).size > 1
|
elsif (segments = str.split(/_/)).size > 1
|
||||||
remainder = []
|
remainder = []
|
||||||
found_assoc = nil
|
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('_'))
|
assoc, klass = unpolymorphize_association(segments.join('_'))
|
||||||
if found_assoc = get_association(assoc, parent)
|
if found_assoc = get_association(assoc, parent)
|
||||||
join = build_or_find_association(found_assoc.name, parent, klass)
|
join = build_or_find_association(
|
||||||
parent, attr_name = get_parent_and_attribute_name(remainder.join('_'), join)
|
found_assoc.name, parent, klass
|
||||||
|
)
|
||||||
|
parent, attr_name = get_parent_and_attribute_name(
|
||||||
|
remainder.join('_'), join
|
||||||
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -89,7 +103,7 @@ module Ransack
|
||||||
def get_association(str, parent = @base)
|
def get_association(str, parent = @base)
|
||||||
klass = klassify parent
|
klass = klassify parent
|
||||||
ransackable_association?(str, klass) &&
|
ransackable_association?(str, klass) &&
|
||||||
klass.reflect_on_all_associations.detect {|a| a.name.to_s == str}
|
klass.reflect_on_all_associations.detect { |a| a.name.to_s == str }
|
||||||
end
|
end
|
||||||
|
|
||||||
def join_dependency(relation)
|
def join_dependency(relation)
|
||||||
|
@ -119,11 +133,12 @@ module Ransack
|
||||||
association_joins = buckets['association_join'] || []
|
association_joins = buckets['association_join'] || []
|
||||||
stashed_association_joins = buckets['stashed_join'] || []
|
stashed_association_joins = buckets['stashed_join'] || []
|
||||||
join_nodes = buckets['join_node'] || []
|
join_nodes = buckets['join_node'] || []
|
||||||
string_joins = (buckets['string_join'] || []).map { |x|
|
string_joins = (buckets['string_join'] || [])
|
||||||
x.strip
|
.map { |x| x.strip }
|
||||||
}.uniq
|
.uniq
|
||||||
|
|
||||||
join_list = relation.send :custom_join_ast, relation.table.from(relation.table), string_joins
|
join_list = relation.send :custom_join_ast,
|
||||||
|
relation.table.from(relation.table), string_joins
|
||||||
|
|
||||||
join_dependency = JoinDependency.new(
|
join_dependency = JoinDependency.new(
|
||||||
relation.klass,
|
relation.klass,
|
||||||
|
@ -139,13 +154,16 @@ module Ransack
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_or_find_association(name, parent = @base, klass = nil)
|
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.reflection.name == name &&
|
||||||
assoc.parent == parent &&
|
assoc.parent == parent &&
|
||||||
(!klass || assoc.reflection.klass == klass)
|
(!klass || assoc.reflection.klass == klass)
|
||||||
end
|
end
|
||||||
unless found_association
|
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
|
found_association = @join_dependency.join_associations.last
|
||||||
# Leverage the stashed association functionality in AR
|
# Leverage the stashed association functionality in AR
|
||||||
@object = @object.joins(found_association)
|
@object = @object.joins(found_association)
|
||||||
|
|
|
@ -8,7 +8,7 @@ module Ransack
|
||||||
module ActiveRecord
|
module ActiveRecord
|
||||||
class Context < ::Ransack::Context
|
class Context < ::Ransack::Context
|
||||||
|
|
||||||
# Redefine a few things that have changed with 3.2.
|
# Redefine a few things for ActiveRecord 3.2.
|
||||||
|
|
||||||
def initialize(object, options = {})
|
def initialize(object, options = {})
|
||||||
super
|
super
|
||||||
|
|
|
@ -17,8 +17,8 @@ module Ransack
|
||||||
end
|
end
|
||||||
|
|
||||||
def ransacker(name, opts = {}, &block)
|
def ransacker(name, opts = {}, &block)
|
||||||
self._ransackers = _ransackers.merge name.to_s => Ransacker.new(
|
self._ransackers = _ransackers.merge name.to_s => Ransacker
|
||||||
self, name, opts, &block)
|
.new(self, name, opts, &block)
|
||||||
end
|
end
|
||||||
|
|
||||||
def ransackable_attributes(auth_object = nil)
|
def ransackable_attributes(auth_object = nil)
|
||||||
|
@ -26,7 +26,8 @@ module Ransack
|
||||||
end
|
end
|
||||||
|
|
||||||
def ransortable_attributes(auth_object = nil)
|
def ransortable_attributes(auth_object = nil)
|
||||||
# Here so users can overwrite the attributes that show up in the sort_select
|
# Here so users can overwrite the attributes
|
||||||
|
# that show up in the sort_select
|
||||||
ransackable_attributes(auth_object)
|
ransackable_attributes(auth_object)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -95,6 +95,5 @@ module Ransack
|
||||||
unescaped.to_s.gsub(/([\\|\%|.])/, '\\\\\\1')
|
unescaped.to_s.gsub(/([\\|\%|.])/, '\\\\\\1')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -61,7 +61,9 @@ module Ransack
|
||||||
obj
|
obj
|
||||||
elsif obj.respond_to? :klass
|
elsif obj.respond_to? :klass
|
||||||
obj.klass
|
obj.klass
|
||||||
elsif obj.respond_to? :base_klass
|
elsif obj.respond_to? :active_record # Rails 3
|
||||||
|
obj.active_record
|
||||||
|
elsif obj.respond_to? :base_klass # Rails 4
|
||||||
obj.base_klass
|
obj.base_klass
|
||||||
else
|
else
|
||||||
raise ArgumentError, "Don't know how to klassify #{obj.inspect}"
|
raise ArgumentError, "Don't know how to klassify #{obj.inspect}"
|
||||||
|
@ -148,5 +150,9 @@ module Ransack
|
||||||
def sortable_attributes(str = '')
|
def sortable_attributes(str = '')
|
||||||
traverse(str).ransortable_attributes(auth_object)
|
traverse(str).ransortable_attributes(auth_object)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def searchable_associations(str = '')
|
||||||
|
traverse(str).ransackable_associations(auth_object)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
require 'action_view'
|
require 'action_view'
|
||||||
require 'simple_form' if
|
|
||||||
(ENV['RANSACK_FORM_BUILDER'] || '').match('SimpleForm')
|
|
||||||
|
|
||||||
require 'simple_form' if
|
require 'simple_form' if
|
||||||
(ENV['RANSACK_FORM_BUILDER'] || '').match('SimpleForm')
|
(ENV['RANSACK_FORM_BUILDER'] || '').match('SimpleForm')
|
||||||
|
@ -109,7 +107,12 @@ module Ransack
|
||||||
|
|
||||||
def predicate_select(options = {}, html_options = {})
|
def predicate_select(options = {}, html_options = {})
|
||||||
options[:compounds] = true if options[:compounds].nil?
|
options[:compounds] = true if options[:compounds].nil?
|
||||||
default = options.delete(:default) || 'cont'
|
if ::ActiveRecord::VERSION::STRING >= "4"
|
||||||
|
default = options.delete(:default) || 'cont'
|
||||||
|
else
|
||||||
|
default = options.delete(:default) || 'eq'
|
||||||
|
end
|
||||||
|
|
||||||
keys = options[:compounds] ? Predicate.names :
|
keys = options[:compounds] ? Predicate.names :
|
||||||
Predicate.names.reject { |k| k.match(/_(any|all)$/) }
|
Predicate.names.reject { |k| k.match(/_(any|all)$/) }
|
||||||
if only = options[:only]
|
if only = options[:only]
|
||||||
|
|
|
@ -23,7 +23,8 @@ module Ransack
|
||||||
end
|
end
|
||||||
|
|
||||||
class Name < String
|
class Name < String
|
||||||
attr_reader :singular, :plural, :element, :collection, :partial_path, :human, :param_key, :route_key, :i18n_key
|
attr_reader :singular, :plural, :element, :collection, :partial_path,
|
||||||
|
:human, :param_key, :route_key, :i18n_key
|
||||||
alias_method :cache_key, :collection
|
alias_method :cache_key, :collection
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
|
|
|
@ -52,4 +52,4 @@ module Ransack
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -19,7 +19,8 @@ module Ransack
|
||||||
m: combinator,
|
m: combinator,
|
||||||
v: predicate.wants_array ? Array(values) : [values]
|
v: predicate.wants_array ? Array(values) : [values]
|
||||||
)
|
)
|
||||||
# TODO: Figure out what to do with multiple types of attributes, if anything.
|
# TODO: Figure out what to do with multiple types of attributes,
|
||||||
|
# if anything.
|
||||||
# Tempted to go with "garbage in, garbage out" on this one
|
# Tempted to go with "garbage in, garbage out" on this one
|
||||||
predicate.validate(condition.values, condition.default_type) ?
|
predicate.validate(condition.values, condition.default_type) ?
|
||||||
condition : nil
|
condition : nil
|
||||||
|
@ -208,14 +209,14 @@ module Ransack
|
||||||
|
|
||||||
def inspect
|
def inspect
|
||||||
data = [
|
data = [
|
||||||
['attributes', a.try(:map, &:name)],
|
['attributes', a.try(:map, &:name)],
|
||||||
['predicate', p],
|
['predicate', p],
|
||||||
['combinator', m],
|
['combinator', m],
|
||||||
['values', v.try(:map, &:value)]
|
['values', v.try(:map, &:value)]
|
||||||
]
|
]
|
||||||
.reject { |e| e[1].blank? }
|
.reject { |e| e[1].blank? }
|
||||||
.map { |v| "#{v[0]}: #{v[1]}" }
|
.map { |v| "#{v[0]}: #{v[1]}" }
|
||||||
.join(', ')
|
.join(', ')
|
||||||
"Condition <#{data}>"
|
"Condition <#{data}>"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -228,4 +229,4 @@ module Ransack
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -129,10 +129,9 @@ module Ransack
|
||||||
when /^(g|c|m|groupings|conditions|combinator)=?$/
|
when /^(g|c|m|groupings|conditions|combinator)=?$/
|
||||||
true
|
true
|
||||||
else
|
else
|
||||||
name.
|
name.split(/_and_|_or_/)
|
||||||
split(/_and_|_or_/).
|
.select { |n| !@context.attribute_method?(n) }
|
||||||
select { |n| !@context.attribute_method?(n) }.
|
.empty?
|
||||||
empty?
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -191,7 +190,6 @@ module Ransack
|
||||||
Predicate.detect_and_strip_from_string!(string)
|
Predicate.detect_and_strip_from_string!(string)
|
||||||
string
|
string
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -31,4 +31,4 @@ module Ransack
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -41,4 +41,4 @@ module Ransack
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -107,4 +107,4 @@ module Ransack
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -29,8 +29,9 @@ module Ransack
|
||||||
end
|
end
|
||||||
|
|
||||||
def name_from_attribute_name(attribute_name)
|
def name_from_attribute_name(attribute_name)
|
||||||
names_by_decreasing_length.
|
names_by_decreasing_length.detect {
|
||||||
detect { |p| attribute_name.to_s.match(/_#{p}$/) }
|
|p| attribute_name.to_s.match(/_#{p}$/)
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def for_attribute_name(attribute_name)
|
def for_attribute_name(attribute_name)
|
||||||
|
@ -75,4 +76,4 @@ module Ransack
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -21,4 +21,4 @@ module Ransack
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -104,7 +104,11 @@ module Ransack
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.i18n_key(klass)
|
def self.i18n_key(klass)
|
||||||
klass.model_name.i18n_key
|
if ActiveRecord::VERSION::MAJOR == 3 && ActiveRecord::VERSION::MINOR == 0
|
||||||
|
klass.model_name.i18n_key.to_s.tr('.', '/')
|
||||||
|
else
|
||||||
|
klass.model_name.i18n_key.to_s
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -15,9 +15,9 @@ Gem::Specification.new do |s|
|
||||||
|
|
||||||
s.rubyforge_project = "ransack"
|
s.rubyforge_project = "ransack"
|
||||||
|
|
||||||
s.add_dependency 'actionpack', '>= 4.0'
|
s.add_dependency 'actionpack', '>= 3.0'
|
||||||
s.add_dependency 'activerecord', '>= 4.0'
|
s.add_dependency 'activerecord', '>= 3.0'
|
||||||
s.add_dependency 'activesupport', '>= 4.0'
|
s.add_dependency 'activesupport', '>= 3.0'
|
||||||
s.add_dependency 'i18n'
|
s.add_dependency 'i18n'
|
||||||
# s.add_dependency 'polyamorous', '~> 0.6.0'
|
# s.add_dependency 'polyamorous', '~> 0.6.0'
|
||||||
s.add_development_dependency 'rspec', '~> 2.8.0'
|
s.add_development_dependency 'rspec', '~> 2.8.0'
|
||||||
|
|
|
@ -5,4 +5,4 @@ Person.blueprint do
|
||||||
only_sort
|
only_sort
|
||||||
only_search
|
only_search
|
||||||
only_admin
|
only_admin
|
||||||
end
|
end
|
||||||
|
|
|
@ -19,4 +19,3 @@ Sham.define do
|
||||||
end
|
end
|
||||||
|
|
||||||
Schema.create
|
Schema.create
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ module Ransack
|
||||||
# ransacker :doubled_name do |parent|
|
# ransacker :doubled_name do |parent|
|
||||||
# Arel::Nodes::InfixOperation.new('||', parent.table[:name], parent.table[:name])
|
# Arel::Nodes::InfixOperation.new('||', parent.table[:name], parent.table[:name])
|
||||||
# end
|
# end
|
||||||
|
|
||||||
it 'creates ransack attributes' do
|
it 'creates ransack attributes' do
|
||||||
s = Person.search(reversed_name_eq: 'htimS cirA')
|
s = Person.search(reversed_name_eq: 'htimS cirA')
|
||||||
s.result.should have(1).person
|
s.result.should have(1).person
|
||||||
|
@ -60,18 +61,20 @@ module Ransack
|
||||||
s.result.count.should eq 1
|
s.result.count.should eq 1
|
||||||
end if defined?(Arel::Nodes::InfixOperation) && sane_adapter?
|
end if defined?(Arel::Nodes::InfixOperation) && sane_adapter?
|
||||||
|
|
||||||
it "should remove empty key value pairs from the params hash" do
|
if ::ActiveRecord::VERSION::STRING >= "4"
|
||||||
s = Person.search(children_reversed_name_eq: '')
|
it "should remove empty key value pairs from the params hash" do
|
||||||
s.result.to_sql.should_not match /LEFT OUTER JOIN/
|
s = Person.search(children_reversed_name_eq: '')
|
||||||
end
|
s.result.to_sql.should_not match /LEFT OUTER JOIN/
|
||||||
|
end
|
||||||
|
|
||||||
it "should keep proper key value pairs in the params hash" do
|
it "should keep proper key value pairs in the params hash" do
|
||||||
s = Person.search(children_reversed_name_eq: 'Testing')
|
s = Person.search(children_reversed_name_eq: 'Testing')
|
||||||
s.result.to_sql.should match /LEFT OUTER JOIN/
|
s.result.to_sql.should match /LEFT OUTER JOIN/
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should function correctly when nil is passed in" do
|
it "should function correctly when nil is passed in" do
|
||||||
s = Person.search(nil)
|
s = Person.search(nil)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should function correctly when using fields with dots in them" do
|
it "should function correctly when using fields with dots in them" do
|
||||||
|
@ -219,4 +222,4 @@ module Ransack
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -48,4 +48,4 @@ module Ransack
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -65,4 +65,4 @@ module Ransack
|
||||||
Ransack.predicates.should_not have_key 'test_array_predicate_all'
|
Ransack.predicates.should_not have_key 'test_array_predicate_all'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#describe 'Ransack' do
|
unless ::ActiveRecord::VERSION::STRING >= "4"
|
||||||
# it 'can be required without errors' do
|
describe 'Ransack' do
|
||||||
# output = `bundle exec ruby -e "require 'ransack'" 2>&1`
|
it 'can be required without errors' do
|
||||||
# output.should be_empty
|
output = `bundle exec ruby -e "require 'ransack'" 2>&1`
|
||||||
# end
|
output.should be_empty
|
||||||
#end
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
|
@ -55,7 +55,11 @@ module Ransack
|
||||||
describe '#sort_link' do
|
describe '#sort_link' do
|
||||||
it 'sort_link for ransack attribute' do
|
it 'sort_link for ransack attribute' do
|
||||||
sort_link = @f.sort_link :name, controller: 'people'
|
sort_link = @f.sort_link :name, controller: 'people'
|
||||||
sort_link.should match /people\?q(%5B|\[)s(%5D|\])=name\+asc/
|
if ActiveRecord::VERSION::STRING =~ /^3\.[1-2]\./
|
||||||
|
sort_link.should match /people\?q%5Bs%5D=name\+asc/
|
||||||
|
else
|
||||||
|
sort_link.should match /people\?q(%5B|\[)s(%5D|\])=name\+asc/
|
||||||
|
end
|
||||||
sort_link.should match /sort_link/
|
sort_link.should match /sort_link/
|
||||||
sort_link.should match /Full Name<\/a>/
|
sort_link.should match /Full Name<\/a>/
|
||||||
end
|
end
|
||||||
|
|
|
@ -33,48 +33,63 @@ module Ransack
|
||||||
controller: 'people'
|
controller: 'people'
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
it { should match /people\?q(%5B|\[)s(%5D|\])=name\+asc/ }
|
it { should match(
|
||||||
|
if ActiveRecord::VERSION::STRING =~ /^3\.[1-2]\./
|
||||||
|
/people\?q%5Bs%5D=name\+asc/
|
||||||
|
else
|
||||||
|
/people\?q(%5B|\[)s(%5D|\])=name\+asc/
|
||||||
|
end)
|
||||||
|
}
|
||||||
it { should match /sort_link desc/ }
|
it { should match /sort_link desc/ }
|
||||||
it { should match /Full Name ▼/ }
|
it { should match /Full Name ▼/ }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#sort_link with default search_key defined as symbol' do
|
describe '#sort_link with default search_key defined as symbol' do
|
||||||
subject { @controller.view_context.
|
subject { @controller.
|
||||||
sort_link(
|
view_context.sort_link(
|
||||||
Person.search({ sorts: ['name desc'] }, search_key: :people_search),
|
Person.search({ :sorts => ['name desc'] }, :search_key => :people_search),
|
||||||
:name,
|
:name, :controller => 'people'
|
||||||
controller: 'people'
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
it { should match /people\?people_search(%5B|\[)s(%5D|\])=name\+asc/ }
|
it { should match(
|
||||||
|
if ActiveRecord::VERSION::STRING =~ /^3\.[1-2]\./
|
||||||
|
/people\?people_search%5Bs%5D=name\+asc/
|
||||||
|
else
|
||||||
|
/people\?people_search(%5B|\[)s(%5D|\])=name\+asc/
|
||||||
|
end)
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#sort_link with default search_key defined as string' do
|
describe '#sort_link with default search_key defined as string' do
|
||||||
subject { @controller.view_context.
|
subject {
|
||||||
sort_link(
|
@controller.view_context.sort_link(
|
||||||
Person.search({ sorts: ['name desc'] }, search_key: 'people_search'),
|
Person.search({ :sorts => ['name desc'] }, :search_key => 'people_search'),
|
||||||
:name,
|
:name, :controller => 'people'
|
||||||
controller: 'people'
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
it { should match /people\?people_search(%5B|\[)s(%5D|\])=name\+asc/ }
|
it { should match(
|
||||||
|
if ActiveRecord::VERSION::STRING =~ /^3\.[1-2]\./
|
||||||
|
/people\?people_search%5Bs%5D=name\+asc/
|
||||||
|
else
|
||||||
|
/people\?people_search(%5B|\[)s(%5D|\])=name\+asc/
|
||||||
|
end)
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'view has existing parameters' do
|
context 'view has existing parameters' do
|
||||||
before do
|
before do
|
||||||
@controller.view_context.
|
@controller.view_context.params.merge!({ :exist => 'existing' })
|
||||||
params.merge!({ exist: 'existing' })
|
|
||||||
end
|
end
|
||||||
describe '#sort_link should not remove existing params' do
|
describe '#sort_link should not remove existing params' do
|
||||||
subject {
|
subject {
|
||||||
@controller.view_context.
|
@controller.view_context.sort_link(
|
||||||
sort_link(
|
Person.search({ :sorts => ['name desc'] }, :search_key => 'people_search'),
|
||||||
Person.search({ sorts: ['name desc'] }, search_key: 'people_search'),
|
:name, :controller => 'people'
|
||||||
:name,
|
)
|
||||||
controller: 'people'
|
}
|
||||||
)
|
it {
|
||||||
|
should match /exist\=existing/
|
||||||
}
|
}
|
||||||
it { should match /exist\=existing/ }
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -42,17 +42,15 @@ module Ransack
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'cont' do
|
describe 'cont' do
|
||||||
|
|
||||||
it_has_behavior 'wildcard escaping', :name_cont,
|
it_has_behavior 'wildcard escaping', :name_cont,
|
||||||
(
|
(if ActiveRecord::Base.connection.adapter_name == "PostgreSQL"
|
||||||
if ActiveRecord::Base.connection.adapter_name == "PostgreSQL"
|
|
||||||
/"people"."name" ILIKE '%\\%\\._\\\\%'/
|
/"people"."name" ILIKE '%\\%\\._\\\\%'/
|
||||||
elsif ActiveRecord::Base.connection.adapter_name == "Mysql2"
|
elsif ActiveRecord::Base.connection.adapter_name == "Mysql2"
|
||||||
/`people`.`name` LIKE '%\\\\%\\\\._\\\\\\\\%'/
|
/`people`.`name` LIKE '%\\\\%\\\\._\\\\\\\\%'/
|
||||||
else
|
else
|
||||||
/"people"."name" LIKE '%%._\\%'/
|
/"people"."name" LIKE '%%._\\%'/
|
||||||
end
|
end) do
|
||||||
) do
|
|
||||||
subject { @s }
|
subject { @s }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -65,15 +63,13 @@ module Ransack
|
||||||
|
|
||||||
describe 'not_cont' do
|
describe 'not_cont' do
|
||||||
it_has_behavior 'wildcard escaping', :name_not_cont,
|
it_has_behavior 'wildcard escaping', :name_not_cont,
|
||||||
(
|
(if ActiveRecord::Base.connection.adapter_name == "PostgreSQL"
|
||||||
if ActiveRecord::Base.connection.adapter_name == "PostgreSQL"
|
|
||||||
/"people"."name" NOT ILIKE '%\\%\\._\\\\%'/
|
/"people"."name" NOT ILIKE '%\\%\\._\\\\%'/
|
||||||
elsif ActiveRecord::Base.connection.adapter_name == "Mysql2"
|
elsif ActiveRecord::Base.connection.adapter_name == "Mysql2"
|
||||||
/`people`.`name` NOT LIKE '%\\\\%\\\\._\\\\\\\\%'/
|
/`people`.`name` NOT LIKE '%\\\\%\\\\._\\\\\\\\%'/
|
||||||
else
|
else
|
||||||
/"people"."name" NOT LIKE '%%._\\%'/
|
/"people"."name" NOT LIKE '%%._\\%'/
|
||||||
end
|
end) do
|
||||||
) do
|
|
||||||
subject { @s }
|
subject { @s }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -89,13 +89,11 @@ module Ransack
|
||||||
|
|
||||||
it 'accepts "attributes" hashes for conditions' do
|
it 'accepts "attributes" hashes for conditions' do
|
||||||
search = Search.new(Person,
|
search = Search.new(Person,
|
||||||
c: {
|
:c => {
|
||||||
'0' => { a: ['name'], p: 'eq', v: ['Ernie'] },
|
'0' => { :a => ['name'], :p => 'eq', :v => ['Ernie'] },
|
||||||
'1' => {
|
'1' => { :a => ['children_name', 'parent_name'],
|
||||||
a: ['children_name', 'parent_name'],
|
:p => 'eq', :v => ['Ernie'], :m => 'or' }
|
||||||
p: 'eq', v: ['Ernie'], m: 'or'
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
conditions = search.base.conditions
|
conditions = search.base.conditions
|
||||||
conditions.should have(2).items
|
conditions.should have(2).items
|
||||||
|
@ -105,8 +103,7 @@ module Ransack
|
||||||
|
|
||||||
it 'creates conditions for custom predicates that take arrays' do
|
it 'creates conditions for custom predicates that take arrays' do
|
||||||
Ransack.configure do |config|
|
Ransack.configure do |config|
|
||||||
config.add_predicate 'ary_pred',
|
config.add_predicate 'ary_pred', :wants_array => true
|
||||||
wants_array: true
|
|
||||||
end
|
end
|
||||||
|
|
||||||
search = Search.new(Person, name_ary_pred: ['Ernie', 'Bert'])
|
search = Search.new(Person, name_ary_pred: ['Ernie', 'Bert'])
|
||||||
|
@ -183,18 +180,42 @@ module Ransack
|
||||||
second.should match /#{children_people_name_field} = 'Bert'/
|
second.should match /#{children_people_name_field} = 'Bert'/
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns distinct records when passed distinct: true' do
|
if ::ActiveRecord::VERSION::STRING >= "4"
|
||||||
search = Search.new(
|
it 'returns distinct records when passed distinct: true' do
|
||||||
Person, g: [
|
search = Search.new(
|
||||||
{ m: 'or',
|
Person, g: [
|
||||||
comments_body_cont: 'e',
|
{ m: 'or',
|
||||||
articles_comments_body_cont: 'e'
|
comments_body_cont: 'e',
|
||||||
}
|
articles_comments_body_cont: 'e'
|
||||||
]
|
}
|
||||||
)
|
]
|
||||||
search.result.load.should have(9000).items
|
)
|
||||||
search.result(distinct: true).should have(10).items
|
search.result.load.should have(9000).items
|
||||||
search.result.load.uniq.should eq search.result(distinct: true).load
|
search.result(distinct: true).should have(10).items
|
||||||
|
search.result.load.uniq.should eq search.result(distinct: true).load
|
||||||
|
end
|
||||||
|
else
|
||||||
|
it 'returns distinct records when passed :distinct => true' do
|
||||||
|
search = Search.new(
|
||||||
|
Person, :g => [
|
||||||
|
{ :m => 'or',
|
||||||
|
:comments_body_cont => 'e',
|
||||||
|
:articles_comments_body_cont => 'e'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
)
|
||||||
|
if ActiveRecord::VERSION::MAJOR == 3
|
||||||
|
all_or_load, uniq_or_distinct = :all, :uniq
|
||||||
|
else
|
||||||
|
all_or_load, uniq_or_distinct = :load, :distinct
|
||||||
|
end
|
||||||
|
search.result.send(all_or_load).
|
||||||
|
should have(920).items
|
||||||
|
search.result(:distinct => true).
|
||||||
|
should have(330).items
|
||||||
|
search.result.send(all_or_load).send(uniq_or_distinct).
|
||||||
|
should eq search.result(:distinct => true).send(all_or_load)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,7 @@ module Ransack
|
||||||
describe '.attribute' do
|
describe '.attribute' do
|
||||||
it 'translate namespaced attribute like AR does' do
|
it 'translate namespaced attribute like AR does' do
|
||||||
ar_translation = ::Namespace::Article.human_attribute_name(:title)
|
ar_translation = ::Namespace::Article.human_attribute_name(:title)
|
||||||
ransack_translation = Ransack::Translate.attribute(
|
ransack_translation = Ransack::Translate.attribute(:title, :context => ::Namespace::Article.search.context)
|
||||||
:title, :context => ::Namespace::Article.search.context
|
|
||||||
)
|
|
||||||
ransack_translation.should eq ar_translation
|
ransack_translation.should eq ar_translation
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -23,7 +23,11 @@ else
|
||||||
end
|
end
|
||||||
|
|
||||||
class Person < ActiveRecord::Base
|
class Person < ActiveRecord::Base
|
||||||
default_scope { order(id: :desc) }
|
if ActiveRecord::VERSION::MAJOR == 3
|
||||||
|
default_scope order('id DESC')
|
||||||
|
else
|
||||||
|
default_scope { order(id: :desc) }
|
||||||
|
end
|
||||||
belongs_to :parent, class_name: 'Person', foreign_key: :parent_id
|
belongs_to :parent, class_name: 'Person', foreign_key: :parent_id
|
||||||
has_many :children, class_name: 'Person', foreign_key: :parent_id
|
has_many :children, class_name: 'Person', foreign_key: :parent_id
|
||||||
has_many :articles
|
has_many :articles
|
||||||
|
@ -57,6 +61,22 @@ class Person < ActiveRecord::Base
|
||||||
column_names + _ransackers.keys - ['only_search', 'only_admin']
|
column_names + _ransackers.keys - ['only_search', 'only_admin']
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.ransackable_attributes(auth_object = nil)
|
||||||
|
if auth_object == :admin
|
||||||
|
column_names + _ransackers.keys - ['only_sort']
|
||||||
|
else
|
||||||
|
column_names + _ransackers.keys - ['only_sort', 'only_admin']
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.ransortable_attributes(auth_object = nil)
|
||||||
|
if auth_object == :admin
|
||||||
|
column_names + _ransackers.keys - ['only_search']
|
||||||
|
else
|
||||||
|
column_names + _ransackers.keys - ['only_search', 'only_admin']
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class Article < ActiveRecord::Base
|
class Article < ActiveRecord::Base
|
||||||
|
@ -72,6 +92,12 @@ module Namespace
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
module Namespace
|
||||||
|
class Article < ::Article
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
class Comment < ActiveRecord::Base
|
class Comment < ActiveRecord::Base
|
||||||
belongs_to :article
|
belongs_to :article
|
||||||
belongs_to :person
|
belongs_to :person
|
||||||
|
@ -128,6 +154,7 @@ module Schema
|
||||||
t.string :notable_type
|
t.string :notable_type
|
||||||
t.string :note
|
t.string :note
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
10.times do
|
10.times do
|
||||||
|
@ -148,6 +175,5 @@ module Schema
|
||||||
Comment.make(
|
Comment.make(
|
||||||
body: 'First post!', article: Article.make(title: 'Hello, world!')
|
body: 'First post!', article: Article.make(title: 'Hello, world!')
|
||||||
)
|
)
|
||||||
|
end
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue