constrainable 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,10 +1,10 @@
1
1
  # Constrainable
2
2
 
3
- Simple filtering for ActiveRecord. Sanitizes simple and readable query parameters -great for building APIs & HTML filters.
3
+ Simple filtering for ActiveRecord. Sanitizes simple and readable query parameters - great for building APIs & HTML filters.
4
4
 
5
5
  ## Straight to the point. Examples:
6
6
 
7
- Let's asume we have a model called Post, defined as:
7
+ Let's assume we have a model called Post, defined as:
8
8
  Post(id: integer, title: string, body: string, author_id: integer, category: string, created_at: datetime, updated_at: datetime)
9
9
 
10
10
  In the simplest possible case you can define a few attributes and start filtering:
@@ -17,7 +17,7 @@ In the simplest possible case you can define a few attributes and start filterin
17
17
 
18
18
  end
19
19
 
20
- # Examle request:
20
+ # Example request:
21
21
  # GET /posts?where[id__not_eq]=1&where[author_id__eq]=2
22
22
  # Params:
23
23
  # "where" => { "id__not_eq" => "1", "author_id__eq" => "2" }
@@ -84,8 +84,8 @@ Integration with controllers, views & filter forms:
84
84
  respond_to :html
85
85
 
86
86
  def index
87
- @filters = Post.constrainable.fliter(params[:where])
88
- @posts = Post.constrain(@filters)
87
+ @filters = Post.constrainable.filter(params[:where])
88
+ @posts = Post.constrain(@filters)
89
89
  respond_with @posts
90
90
  end
91
91
  end
@@ -9,6 +9,7 @@ module Bsm::Constrainable::Field
9
9
  autoload :Timestamp,'bsm/constrainable/field/common'
10
10
  autoload :Datetime, 'bsm/constrainable/field/common'
11
11
  autoload :Date, 'bsm/constrainable/field/common'
12
+ autoload :Boolean, 'bsm/constrainable/field/common'
12
13
 
13
14
  register self::Number
14
15
  register self::Integer
@@ -17,4 +18,5 @@ module Bsm::Constrainable::Field
17
18
  register self::Timestamp
18
19
  register self::Datetime
19
20
  register self::Date
21
+ register self::Boolean
20
22
  end
@@ -11,12 +11,12 @@ class Bsm::Constrainable::Field::Base
11
11
  @kind ||= name.demodulize.underscore.to_sym
12
12
  end
13
13
 
14
- attr_reader :name, :operators, :attribute, :scope
14
+ attr_reader :name, :operators, :attribute, :scope, :options
15
15
 
16
16
  # Accepts a name and options. Valid options are:
17
17
  # * <tt>:using</tt> - a Symbol or a Proc pointing to a DB column, optional (uses name by default)
18
18
  # * <tt>:with</tt> - a list of operators to use
19
- # * <tt>:scope</tt> - a Proc containing additonal scopes
19
+ # * <tt>:scope</tt> - a Proc containing additional scopes
20
20
  #
21
21
  # Examples:
22
22
  #
@@ -28,10 +28,11 @@ class Bsm::Constrainable::Field::Base
28
28
  #
29
29
  def initialize(name, options = {})
30
30
  @name = name.to_s
31
- @attribute = options[:using] || name
32
- @operators = Set.new(self.class.operators & Array.wrap(options[:with]))
31
+ @options = options.dup
32
+ @attribute = @options.delete(:using) || name
33
+ @operators = Set.new(self.class.operators & Array.wrap(@options.delete(:with)))
33
34
  @operators = Set.new(self.class.defaults) if @operators.empty?
34
- @scope = options[:scope]
35
+ @scope = @options.delete(:scope)
35
36
  end
36
37
 
37
38
  # Merge params into a relation
@@ -23,6 +23,11 @@ module Bsm::Constrainable::Field
23
23
 
24
24
  class String < Base
25
25
  self.operators = [:eq, :not_eq]
26
+
27
+ def _convert(v)
28
+ result = super
29
+ result.blank? && !options[:allow_blank] ? nil : result
30
+ end
26
31
  end
27
32
 
28
33
  class Timestamp < Base
@@ -43,4 +48,19 @@ module Bsm::Constrainable::Field
43
48
  v.to_date rescue nil
44
49
  end
45
50
  end
51
+
52
+ class Boolean < Base
53
+ self.operators = [:eq, :not_eq]
54
+
55
+ TRUE_VALUES = ["true", "TRUE", "t", "T", "1", 1].to_set.freeze
56
+ FALSE_VALUES = ["false", "FALSE", "f", "F", "0", 0].to_set.freeze
57
+
58
+ protected
59
+
60
+ def _convert(v)
61
+ result = super
62
+ TRUE_VALUES.include?(result) || (FALSE_VALUES.include?(result) ? false : nil)
63
+ end
64
+ end
65
+
46
66
  end
@@ -1,5 +1,4 @@
1
1
  class Bsm::Constrainable::Operation::Base
2
- extend ActiveSupport::Memoizable
3
2
 
4
3
  def self.kind
5
4
  name.demodulize.underscore.to_sym
@@ -27,9 +26,9 @@ class Bsm::Constrainable::Operation::Base
27
26
  end
28
27
 
29
28
  def clause
30
- valid? ? _clause : nil
29
+ return @clause if defined?(@clause)
30
+ @clause ||= valid? ? _clause : nil
31
31
  end
32
- memoize :clause
33
32
 
34
33
  protected
35
34
 
@@ -38,18 +37,16 @@ class Bsm::Constrainable::Operation::Base
38
37
  end
39
38
 
40
39
  def normalized
41
- field.convert(parsed)
40
+ @normalized ||= field.convert(parsed)
42
41
  end
43
- memoize :normalized
44
42
 
45
43
  def attribute
46
- case field.attribute
44
+ @attribute ||= case field.attribute
47
45
  when Proc
48
46
  field.attribute.call(relation)
49
47
  else
50
48
  relation.table[field.attribute]
51
49
  end
52
50
  end
53
- memoize :attribute
54
51
 
55
52
  end
@@ -1,7 +1,7 @@
1
1
  # Extension for ActiveRecord::Relation
2
2
  module Bsm::Constrainable::Relation
3
3
 
4
- # Apply contraints. Example:
4
+ # Apply constraints. Example:
5
5
  #
6
6
  # Post.constrain("created_at__lt" => "2011-01-01")
7
7
  #
@@ -40,7 +40,7 @@ class Bsm::Constrainable::Schema < Hash
40
40
  # # Complex example, using an attribute from another table, and ensure it's included (LEFT OUTER JOIN)
41
41
  # match :author, :using => proc { Author.scope.table[:name] }, :scope => { includes(:author) }, :as => :string, :with => [:eq, :matches]
42
42
  #
43
- # There are also several short-cutrs available. Examples:
43
+ # There are also several short-cuts available. Examples:
44
44
  #
45
45
  # timestamp :created, :using => :created_at, :with => [:lt, :between]
46
46
  # number :id, :author_id
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: constrainable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.6.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,22 +9,22 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-10-21 00:00:00.000000000Z
12
+ date: 2012-01-23 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
- name: abstract
16
- requirement: &24194140 !ruby/object:Gem::Requirement
15
+ name: activerecord
16
+ requirement: &12912960 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
20
20
  - !ruby/object:Gem::Version
21
- version: '0'
21
+ version: 3.0.0
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *24194140
24
+ version_requirements: *12912960
25
25
  - !ruby/object:Gem::Dependency
26
- name: activerecord
27
- requirement: &24193560 !ruby/object:Gem::Requirement
26
+ name: activesupport
27
+ requirement: &12912280 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,18 +32,62 @@ dependencies:
32
32
  version: 3.0.0
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *24193560
35
+ version_requirements: *12912280
36
36
  - !ruby/object:Gem::Dependency
37
- name: activesupport
38
- requirement: &24193060 !ruby/object:Gem::Requirement
37
+ name: rspec
38
+ requirement: &12911680 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
42
42
  - !ruby/object:Gem::Version
43
- version: 3.0.0
44
- type: :runtime
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *12911680
47
+ - !ruby/object:Gem::Dependency
48
+ name: rspec-rails
49
+ requirement: &12910780 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *12910780
58
+ - !ruby/object:Gem::Dependency
59
+ name: sqlite3-ruby
60
+ requirement: &12909920 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *12909920
69
+ - !ruby/object:Gem::Dependency
70
+ name: shoulda-matchers
71
+ requirement: &12908980 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *12908980
80
+ - !ruby/object:Gem::Dependency
81
+ name: actionpack
82
+ requirement: &12907980 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
45
89
  prerelease: false
46
- version_requirements: *24193060
90
+ version_requirements: *12907980
47
91
  description: Sanitizes simple and readable query parameters -great for building APIs
48
92
  & HTML filters
49
93
  email: dimitrij@blacksquaremedia.com