Fix/add specs, remove duplicate base.rb for edge and 3.0
This commit is contained in:
parent
747b414110
commit
cec4e3d64f
|
@ -1,18 +1,17 @@
|
|||
require 'ransack/adapters/active_record/base'
|
||||
ActiveRecord::Base.extend Ransack::Adapters::ActiveRecord::Base
|
||||
|
||||
case ActiveRecord::VERSION::STRING
|
||||
when /^3\.0\./
|
||||
require 'ransack/adapters/active_record/3.0/base'
|
||||
require 'ransack/adapters/active_record/3.0/join_dependency'
|
||||
require 'ransack/adapters/active_record/3.0/join_association'
|
||||
require 'ransack/adapters/active_record/3.0/context'
|
||||
|
||||
ActiveRecord::Base.extend Ransack::Adapters::ActiveRecord::Base
|
||||
ActiveRecord::Associations::ClassMethods::JoinDependency.send :include, Ransack::Adapters::ActiveRecord::JoinDependency
|
||||
else
|
||||
require 'ransack/adapters/active_record/base'
|
||||
require 'ransack/adapters/active_record/join_dependency'
|
||||
require 'ransack/adapters/active_record/join_association'
|
||||
require 'ransack/adapters/active_record/context'
|
||||
|
||||
ActiveRecord::Base.extend Ransack::Adapters::ActiveRecord::Base
|
||||
ActiveRecord::Associations::JoinDependency.send :include, Ransack::Adapters::ActiveRecord::JoinDependency
|
||||
end
|
|
@ -1,33 +0,0 @@
|
|||
module Ransack
|
||||
module Adapters
|
||||
module ActiveRecord
|
||||
module Base
|
||||
|
||||
def self.extended(base)
|
||||
alias :search :ransack unless base.method_defined? :search
|
||||
base.instance_eval do
|
||||
class_attribute :_ransackers
|
||||
self._ransackers ||= {}
|
||||
end
|
||||
end
|
||||
|
||||
def ransack(params = {}, options = {})
|
||||
Search.new(self, params, options)
|
||||
end
|
||||
|
||||
def ransacker(name, opts = {}, &block)
|
||||
Ransacker.new(self, name, opts, &block)
|
||||
end
|
||||
|
||||
def ransackable_attributes(auth_object)
|
||||
column_names + _ransackers.keys
|
||||
end
|
||||
|
||||
def ransackable_associations(auth_object)
|
||||
reflect_on_all_associations.map {|a| a.name.to_s}
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -20,4 +20,147 @@ class ::ActiveRecord::Associations::ClassMethods::JoinDependency::JoinBase
|
|||
:engine => active_record.arel_engine,
|
||||
:columns => active_record.columns)
|
||||
end
|
||||
end
|
||||
|
||||
module Arel
|
||||
|
||||
class Table
|
||||
alias :table_name :name
|
||||
|
||||
def [] name
|
||||
::Arel::Attribute.new self, name.to_sym
|
||||
end
|
||||
end
|
||||
|
||||
module Nodes
|
||||
class Node
|
||||
def not
|
||||
Nodes::Not.new self
|
||||
end
|
||||
end
|
||||
|
||||
remove_const :And
|
||||
class And < Arel::Nodes::Node
|
||||
attr_reader :children
|
||||
|
||||
def initialize children, right = nil
|
||||
unless Array === children
|
||||
children = [children, right]
|
||||
end
|
||||
@children = children
|
||||
end
|
||||
|
||||
def left
|
||||
children.first
|
||||
end
|
||||
|
||||
def right
|
||||
children[1]
|
||||
end
|
||||
end
|
||||
|
||||
class NamedFunction < Arel::Nodes::Function
|
||||
attr_accessor :name, :distinct
|
||||
|
||||
include Arel::Predications
|
||||
|
||||
def initialize name, expr, aliaz = nil
|
||||
super(expr, aliaz)
|
||||
@name = name
|
||||
@distinct = false
|
||||
end
|
||||
end
|
||||
|
||||
class InfixOperation < Binary
|
||||
include Arel::Expressions
|
||||
include Arel::Predications
|
||||
|
||||
attr_reader :operator
|
||||
|
||||
def initialize operator, left, right
|
||||
super(left, right)
|
||||
@operator = operator
|
||||
end
|
||||
end
|
||||
|
||||
class Multiplication < InfixOperation
|
||||
def initialize left, right
|
||||
super(:*, left, right)
|
||||
end
|
||||
end
|
||||
|
||||
class Division < InfixOperation
|
||||
def initialize left, right
|
||||
super(:/, left, right)
|
||||
end
|
||||
end
|
||||
|
||||
class Addition < InfixOperation
|
||||
def initialize left, right
|
||||
super(:+, left, right)
|
||||
end
|
||||
end
|
||||
|
||||
class Subtraction < InfixOperation
|
||||
def initialize left, right
|
||||
super(:-, left, right)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module Visitors
|
||||
class ToSql
|
||||
def column_for attr
|
||||
name = attr.name.to_s
|
||||
table = attr.relation.table_name
|
||||
|
||||
column_cache[table][name]
|
||||
end
|
||||
|
||||
def column_cache
|
||||
@column_cache ||= Hash.new do |hash, key|
|
||||
hash[key] = Hash[
|
||||
@engine.connection.columns(key, "#{key} Columns").map do |c|
|
||||
[c.name, c]
|
||||
end
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
def visit_Arel_Nodes_InfixOperation o
|
||||
"#{visit o.left} #{o.operator} #{visit o.right}"
|
||||
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}" : ''}"
|
||||
end
|
||||
|
||||
def visit_Arel_Nodes_And o
|
||||
o.children.map { |x| visit x }.join ' AND '
|
||||
end
|
||||
|
||||
def visit_Arel_Nodes_Not o
|
||||
"NOT (#{visit o.expr})"
|
||||
end
|
||||
|
||||
def visit_Arel_Nodes_Values o
|
||||
"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 ', '})"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module Predications
|
||||
def as other
|
||||
Nodes::As.new self, Nodes::SqlLiteral.new(other)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -19,12 +19,11 @@ module Ransack
|
|||
Ransacker.new(self, name, opts, &block)
|
||||
end
|
||||
|
||||
# TODO: Let's actually do some authorization. Whitelist-only.
|
||||
def ransackable_attributes(auth_object)
|
||||
def ransackable_attributes(auth_object = nil)
|
||||
column_names + _ransackers.keys
|
||||
end
|
||||
|
||||
def ransackable_associations(auth_object)
|
||||
def ransackable_associations(auth_object = nil)
|
||||
reflect_on_all_associations.map {|a| a.name.to_s}
|
||||
end
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ module Ransack
|
|||
mattr_accessor :predicates
|
||||
self.predicates = {}
|
||||
|
||||
def self.predicate_keys
|
||||
def predicate_keys
|
||||
predicates.keys.sort {|a,b| b.length <=> a.length}
|
||||
end
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ module Ransack
|
|||
|
||||
def extract_attributes_and_predicate(key)
|
||||
str = key.dup
|
||||
name = Ransack::Configuration.predicate_keys.detect {|p| str.sub!(/_#{p}$/, '')}
|
||||
name = Ransack.predicate_keys.detect {|p| str.sub!(/_#{p}$/, '')}
|
||||
predicate = Predicate.named(name)
|
||||
raise ArgumentError, "No valid predicate for #{key}" unless predicate
|
||||
attributes = str.split(/_and_|_or_/)
|
||||
|
|
|
@ -198,7 +198,7 @@ module Ransack
|
|||
|
||||
def strip_predicate_and_index(str)
|
||||
string = str.split(/\(/).first
|
||||
Ransack::Configuration.predicate_keys.detect {|p| string.sub!(/_#{p}$/, '')}
|
||||
Ransack.predicate_keys.detect {|p| string.sub!(/_#{p}$/, '')}
|
||||
string
|
||||
end
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ module Ransack
|
|||
original_name = key.to_s
|
||||
base_class = context.klass
|
||||
base_ancestors = base_class.ancestors.select { |x| x.respond_to?(:model_name) }
|
||||
predicate = Ransack::Configuration.predicate_keys.detect {|p| original_name.match(/_#{p}$/)}
|
||||
predicate = Ransack.predicate_keys.detect {|p| original_name.match(/_#{p}$/)}
|
||||
attributes_str = original_name.sub(/_#{predicate}$/, '')
|
||||
attribute_names = attributes_str.split(/_and_|_or_/)
|
||||
combinator = attributes_str.match(/_and_/) ? :and : :or
|
||||
|
|
|
@ -2,9 +2,9 @@ require 'spec_helper'
|
|||
|
||||
module Ransack
|
||||
describe Configuration do
|
||||
it 'yields self on configure' do
|
||||
Ransack.configure do
|
||||
self.should eq Ransack::Configuration
|
||||
it 'yields Ransack on configure' do
|
||||
Ransack.configure do |config|
|
||||
config.should eq Ransack
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -32,9 +32,43 @@ module Ransack
|
|||
|
||||
it 'selects previously-entered time values with datetime_select' do
|
||||
@s.created_at_eq = [2011, 1, 2, 3, 4, 5]
|
||||
html = @f.datetime_select :created_at_eq
|
||||
[2011, 1, 2, 3, 4, 5].each do |val|
|
||||
html.should match /<option selected="selected" value="#{val}">#{val}<\/option>/o
|
||||
html = @f.datetime_select :created_at_eq, :use_month_numbers => true, :include_seconds => true
|
||||
%w(2011 1 2 03 04 05).each do |val|
|
||||
html.should match /<option selected="selected" value="#{val}">#{val}<\/option>/
|
||||
end
|
||||
end
|
||||
|
||||
it 'localizes labels' do
|
||||
html = @f.label :name_cont
|
||||
html.should match /Full Name contains/
|
||||
end
|
||||
|
||||
it 'localizes submit' do
|
||||
html = @f.submit
|
||||
html.should match /"Search"/
|
||||
end
|
||||
|
||||
it 'returns ransackable attributes for attribute_select' do
|
||||
html = @f.attribute_select
|
||||
html.split(/\n/).should have(Person.ransackable_attributes.size + 1).lines
|
||||
Person.ransackable_attributes.each do |attribute|
|
||||
html.should match /<option value="#{attribute}">/
|
||||
end
|
||||
end
|
||||
|
||||
it 'returns ransackable attributes for associations in attribute_select with associations' do
|
||||
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|
|
||||
html.should match /<option value="#{attribute}">/
|
||||
end
|
||||
end
|
||||
|
||||
it 'returns option groups for base and associations in attribute_select with associations' do
|
||||
html = @f.attribute_select :associations => ['articles']
|
||||
[Person, Article].each do |model|
|
||||
html.should match /<optgroup label="#{model}">/
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ require 'faker'
|
|||
require 'ransack'
|
||||
|
||||
Time.zone = 'Eastern Time (US & Canada)'
|
||||
I18n.load_path += Dir[File.join(File.dirname(__FILE__), 'support', '*.yml')]
|
||||
|
||||
Dir[File.expand_path('../{helpers,support,blueprints}/*.rb', __FILE__)].each do |f|
|
||||
require f
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
en:
|
||||
ransack:
|
||||
attributes:
|
||||
person:
|
||||
name: Full Name
|
Loading…
Reference in New Issue