Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Empty string fields are ignore by default, add Boolean field type #1

Merged
merged 3 commits into from

1 participant

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
10 README.markdown
@@ -1,10 +1,10 @@
# Constrainable
-Simple filtering for ActiveRecord. Sanitizes simple and readable query parameters -great for building APIs & HTML filters.
+Simple filtering for ActiveRecord. Sanitizes simple and readable query parameters - great for building APIs & HTML filters.
## Straight to the point. Examples:
-Let's asume we have a model called Post, defined as:
+Let's assume we have a model called Post, defined as:
Post(id: integer, title: string, body: string, author_id: integer, category: string, created_at: datetime, updated_at: datetime)
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
end
- # Examle request:
+ # Example request:
# GET /posts?where[id__not_eq]=1&where[author_id__eq]=2
# Params:
# "where" => { "id__not_eq" => "1", "author_id__eq" => "2" }
@@ -84,8 +84,8 @@ Integration with controllers, views & filter forms:
respond_to :html
def index
- @filters = Post.constrainable.fliter(params[:where])
- @posts = Post.constrain(@filters)
+ @filters = Post.constrainable.filter(params[:where])
+ @posts = Post.constrain(@filters)
respond_with @posts
end
end
View
2  lib/bsm/constrainable/field.rb
@@ -9,6 +9,7 @@ module Bsm::Constrainable::Field
autoload :Timestamp,'bsm/constrainable/field/common'
autoload :Datetime, 'bsm/constrainable/field/common'
autoload :Date, 'bsm/constrainable/field/common'
+ autoload :Boolean, 'bsm/constrainable/field/common'
register self::Number
register self::Integer
@@ -17,4 +18,5 @@ module Bsm::Constrainable::Field
register self::Timestamp
register self::Datetime
register self::Date
+ register self::Boolean
end
View
11 lib/bsm/constrainable/field/base.rb
@@ -11,12 +11,12 @@ def self.kind
@kind ||= name.demodulize.underscore.to_sym
end
- attr_reader :name, :operators, :attribute, :scope
+ attr_reader :name, :operators, :attribute, :scope, :options
# Accepts a name and options. Valid options are:
# * <tt>:using</tt> - a Symbol or a Proc pointing to a DB column, optional (uses name by default)
# * <tt>:with</tt> - a list of operators to use
- # * <tt>:scope</tt> - a Proc containing additonal scopes
+ # * <tt>:scope</tt> - a Proc containing additional scopes
#
# Examples:
#
@@ -28,10 +28,11 @@ def self.kind
#
def initialize(name, options = {})
@name = name.to_s
- @attribute = options[:using] || name
- @operators = Set.new(self.class.operators & Array.wrap(options[:with]))
+ @options = options.dup
+ @attribute = @options.delete(:using) || name
+ @operators = Set.new(self.class.operators & Array.wrap(@options.delete(:with)))
@operators = Set.new(self.class.defaults) if @operators.empty?
- @scope = options[:scope]
+ @scope = @options.delete(:scope)
end
# Merge params into a relation
View
19 lib/bsm/constrainable/field/common.rb
@@ -23,6 +23,11 @@ class Decimal < Number
class String < Base
self.operators = [:eq, :not_eq]
+
+ def _convert(v)
+ result = super
+ result.blank? && !options[:allow_blank] ? nil : result
+ end
end
class Timestamp < Base
@@ -43,4 +48,18 @@ def _convert(v)
v.to_date rescue nil
end
end
+
+ class Boolean < Base
+ self.operators = [:eq, :not_eq]
+
+ TRUE_VALUES = ["true", "1"]
+
+ protected
+
+ def _convert(v)
+ result = super
+ result.blank? ? nil : TRUE_VALUES.include?(result)
+ end
+ end
+
end
View
2  lib/bsm/constrainable/relation.rb
@@ -1,7 +1,7 @@
# Extension for ActiveRecord::Relation
module Bsm::Constrainable::Relation
- # Apply contraints. Example:
+ # Apply constraints. Example:
#
# Post.constrain("created_at__lt" => "2011-01-01")
#
View
2  lib/bsm/constrainable/schema.rb
@@ -40,7 +40,7 @@ def fields(*names)
# # Complex example, using an attribute from another table, and ensure it's included (LEFT OUTER JOIN)
# match :author, :using => proc { Author.scope.table[:name] }, :scope => { includes(:author) }, :as => :string, :with => [:eq, :matches]
#
- # There are also several short-cutrs available. Examples:
+ # There are also several short-cuts available. Examples:
#
# timestamp :created, :using => :created_at, :with => [:lt, :between]
# number :id, :author_id
View
4 spec/bsm/constrainable/field/base_spec.rb
@@ -63,5 +63,9 @@ def merge(name, operator, value)
rel.first.should == posts(:article)
end
+ it 'should store unrecognized options' do
+ Bsm::Constrainable::Field::String.new("some", :allow_blank => true).options.should == { :allow_blank => true }
+ end
+
end
View
19 spec/bsm/constrainable/field/common_spec.rb
@@ -2,9 +2,7 @@
describe "Common Fields" do
- def subject(value = "")
- described_class.new(value)
- end
+ let(:subject) { described_class.new('') }
describe Bsm::Constrainable::Field::Number do
it { subject.class.should have(9).operators }
@@ -32,6 +30,11 @@ def subject(value = "")
it { subject.class.should have(2).operators }
it { subject.convert(1).should == "1" }
it { subject.convert(["a", 1]).should == ["a", "1"] }
+ it { subject.convert("").should be_nil }
+ it {
+ subject.options[:allow_blank] = true
+ subject.convert("").should == ""
+ }
end
describe Bsm::Constrainable::Field::Timestamp do
@@ -52,5 +55,15 @@ def subject(value = "")
it { subject.convert("2011-11-11 11:11").should == Date.civil(2011, 11, 11) }
end
+ describe Bsm::Constrainable::Field::Boolean do
+ it { subject.class.should have(2).operators }
+ it { subject.convert("true").should == true }
+ it { subject.convert("1").should == true }
+ it { subject.convert("false").should == false }
+ it { subject.convert("0").should == false }
+ it { subject.convert("").should == nil }
+ it { subject.convert("invalid").should == nil }
+ end
+
end
Something went wrong with that request. Please try again.