Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Predicated is a simple predicate model for Ruby. It provides useful predicate transformations and operations.
Ruby
Branch: master

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
.bundle
lib
test
test_integration
.gitignore
Gemfile
HISTORY.md
LICENSE
README.markdown
Rakefile
predicated.gemspec

README.markdown

Abstract

Predicated is a simple predicate model for Ruby. It provides useful predicate transformations and operations.

Tracker project: http://www.pivotaltracker.com/projects/95014

Transformations

  • From:
    • json
    • xml
    • url part, ex: "!(a=1&b=2|c=3)"
    • callable objects (lambdas/procs, and therefore blocks) - ruby 1.8.x only
    • ruby code - ruby 1.8.x only
  • To:
    • json
    • xml
    • sql where clause via arel
    • solr query string
    • english sentence, ex: "'a' is not equal to 'b'"

Usage

Note: The test suite acts as a comprehensive usage guide.

Evaluate a predicate:

require "predicated/evaluate"
include Predicated

Predicate { Eq(1, 2) }.evaluate == false
Predicate { Lt(1, 2) }.evaluate == true
Predicate { Or(Lt(1, 2),Eq(1, 2)) }.evaluate == true

x = 1
Predicate { Lt(x, 2) }.evaluate == true

Parse a predicate from part of a url and then turn it into a sql where clause:

require "predicated/from/url_part"
require "predicated/to/arel"

predicate = Predicated::Predicate.from_url_part("(color=red|color=green)&size=large")

predicate.inspect == 
  "And(Or(Eq('color','red'),Eq('color','green')),Eq('size','large'))" 

predicate.to_arel(Table(:shirt)).to_sql == 
  %{(("shirt"."color" = 'red' OR "shirt"."color" = 'green') AND "shirt"."size" = 'large')} 

Parse a predicate from json and then turn it into a solr query string:

require "predicated/from/json"
require "predicated/to/solr"

predicate = Predicated::Predicate.from_json_str(%{
  {"and":[{"or":[["color","==","red"],["color","==","green"]]},["size","==","large"]]}
})

predicate.inspect == "And(Or(Eq('color','red'),Eq('color','green')),Eq('size','large'))" 

predicate.to_solr == "((color:red OR color:green) AND size:large)" 

From json:

require "predicated/from/json"

Predicated::Predicate.from_json_str(%{
  {"and":[
    {"or":[
      ["color","==","red"],
      ["color","==","green"]
    ]},
    ["size","==","large"]
  ]}
}).inspect == "And(Or(Eq('color','red'),Eq('color','green')),Eq('size','large'))" 

From xml:

require "predicated/from/xml"

Predicated::Predicate.from_xml(%{
  <and>
    <or>
      <equal><left>color</left><right>red</right></equal>
      <equal><left>color</left><right>green</right></equal>
    </or>
    <equal><left>size</left><right>large</right></equal>
  </and>
}).inspect == "And(Or(Eq('color','red'),Eq('color','green')),Eq('size','large'))" 

From url part:

require "predicated/from/url_part"

Predicated::Predicate.from_url_part("(color=red|color=green)&size=large").inspect ==
  "And(Or(Eq('color','red'),Eq('color','green')),Eq('size','large'))" 

From callable object:

require "predicated/from/callable_object"

Predicated::Predicate.from_callable_object{('color'=='red' || 'color'=='green') && 'size'=='large'}.inspect ==
  "And(Or(Eq('color','red'),Eq('color','green')),Eq('size','large'))" 

From ruby code string:

require "predicated/from/ruby_code_string"

Predicated::Predicate.from_ruby_code_string("('color'=='red' || 'color'=='green') && 'size'=='large'").inspect ==
  "And(Or(Eq('color','red'),Eq('color','green')),Eq('size','large'))" 

To json:

require "predicated/to/json"
include Predicated

Predicate{And(Or(Eq('color','red'),Eq('color','green')),Eq('size','large'))}.to_json_str ==
%{
  {"and":[
    {"or":[
      ["color","==","red"],
      ["color","==","green"]
    ]},
    ["size","==","large"]
  ]}
}

To xml:

require "predicated/to/xml"
include Predicated

Predicate{And(Or(Eq('color','red'),Eq('color','green')),Eq('size','large'))}.to_xml ==
%{
  <and>
    <or>
      <equal><left>color</left><right>red</right></equal>
      <equal><left>color</left><right>green</right></equal>
    </or>
    <equal><left>size</left><right>large</right></equal>
  </and>      
}

To arel (sql where clause):

require "predicated/to/arel"
include Predicated

Predicate{And(Or(Eq('color','red'),Eq('color','green')),Eq('size','large'))}.to_arel(Table(:shirt)).to_sql ==
  %{(("shirt"."color" = 'red' OR "shirt"."color" = 'green') AND "shirt"."size" = 'large')}

To solr query string:

require "predicated/to/solr"
include Predicated

Predicate{And(Or(Eq('color','red'),Eq('color','green')),Eq('size','large'))}.to_solr ==
  "((color:red OR color:green) AND size:large)"

To sentence:

require "predicated/to/sentence"
include Predicated

Predicate{ And(Eq("a",1),Eq("b",2)) }.to_sentence == 
  "'a' is equal to 1 and 'b' is equal to 2"

Predicate{ Gt("a",1) }.to_negative_sentence == 
  "'a' is not greater than 1" 

Testing Notes

Right now this project makes use of Wrong for assertions. Wrong uses this project. It's kind of neat in an eat-your-own-dogfood sense, but it's possible that this will be problematic over time (particularly when changes in this project cause assertions to behave differently - if even temporarily).

A middle ground is to make "from ruby string" and "from callable object" use minitest asserts, since these are the "interesting" parts of Predicated relied on by Wrong.

Something went wrong with that request. Please try again.