Relata 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Rakefile CHANGED
@@ -27,7 +27,7 @@ PKG_FILES = FileList[ '[a-zA-Z]*', 'generators/**/*', 'lib/**/*', 'rails/**/*',
27
27
 
28
28
  spec = Gem::Specification.new do |s|
29
29
  s.name = "Relata"
30
- s.version = "0.0.2"
30
+ s.version = "0.0.3"
31
31
  s.author = "Anderson Leite, Guilherme Silveira"
32
32
  s.email = "anderson.leite@caelum.com.br"
33
33
  s.homepage = "http://github.com/caelum/relata"
data/init.rb CHANGED
@@ -4,4 +4,4 @@ require 'ruby-debug'
4
4
  require 'active_record'
5
5
  require "active_support"
6
6
 
7
- require "filtered_relation"
7
+ require "relata"
@@ -0,0 +1,3 @@
1
+ module Relata
2
+ require 'relata/filter'
3
+ end
@@ -0,0 +1,42 @@
1
+ # in case you did not require the entire relata plugin
2
+ module Relata
3
+ module Dsl
4
+ end
5
+ end
6
+
7
+ require 'relata/dsl/conditions'
8
+ require 'relata/dsl/constraints'
9
+ require 'relata/dsl/custom_relation'
10
+ require 'relata/dsl/field_search'
11
+ require 'relata/dsl/missed_builder'
12
+ require 'relata/dsl/querys/multiple'
13
+ require 'relata/dsl/querys/simple'
14
+ require 'relata/dsl/querys/fields'
15
+ require 'relata/dsl/querys/belongs'
16
+
17
+ module Relata::Dsl::Relation
18
+
19
+ # extended where clause that allows symbol and custom dsl lookup
20
+ #
21
+ # examples:
22
+ # where(:body).like?("%guilherme%")
23
+ # where { body.like?("%guilherme%")
24
+ #
25
+ # While the last will delegate to the MissedBuilder component
26
+ # the symbol based query will delegate query builder to CustomRelation.
27
+ def where(*args, &block)
28
+ if args.size==0 && block
29
+ Relata::Dsl::MissedBuilder.new(self).instance_eval(&block)
30
+ elsif args.size==1 && args[0].is_a?(Symbol)
31
+ relation = scoped
32
+ relation.extend Relata::Dsl::CustomRelation
33
+ relation.using(self, args[0])
34
+ else
35
+ super(*args, &block)
36
+ end
37
+ end
38
+ end
39
+
40
+ class ActiveRecord::Relation
41
+ include Relata::Dsl::Relation
42
+ end
@@ -0,0 +1,65 @@
1
+ # = Conditions
2
+ # A custom set of conditions that can be applied
3
+ # to a query
4
+ module Relata::Dsl::Conditions
5
+
6
+ # Return all objects whith exactly X associated objects
7
+ # Post.where(:comments).count.eq(2)
8
+ def eq(value)
9
+ add_filter("= #{value}")
10
+ end
11
+
12
+ # Return all objects whith more or exactly X associated objects
13
+ # Post.where(:comments).count.ge(2)
14
+ def ge(value)
15
+ add_filter(">= #{value}")
16
+ end
17
+
18
+ # Return all objects whith more or exactly X associated objects
19
+ # Post.where(:comments).count.greater_or_equals(2)
20
+ def greater_or_equals(value)
21
+ ge(value)
22
+ end
23
+
24
+ # Return all objects whith more than X associated objects
25
+ # Post.where(:comments).count.gt(2)
26
+ def gt(value)
27
+ add_filter("> #{value}")
28
+ end
29
+
30
+ # Return all objects whith more than X associated objects
31
+ # Alias for "gt"
32
+ # Post.where(:comments).count.greater_than(2)
33
+ def greater_than(value)
34
+ gt(value)
35
+ end
36
+
37
+ # Return all objects whith less or equals X associated objects
38
+ # Post.where(:comments).count.le(2)
39
+ def le(value)
40
+ add_filter("<= #{value}")
41
+ end
42
+
43
+ # Return all objects whith less than X associated objects
44
+ # Post.where(:comments).count.lt(2)
45
+ def lt(value)
46
+ add_filter("< #{value}")
47
+ end
48
+
49
+ # Return all objects whith less than X associated object
50
+ # Alias for "lt"
51
+ # Post.where(:comments).count.lesser_than(2)
52
+ def lesser_than(value)
53
+ lt value
54
+ end
55
+
56
+ # Whether this relation has at least one element.
57
+ # Post.where(:comments).exists?
58
+ def exists?
59
+ if @relation_search.nil?
60
+ count.exists?
61
+ else
62
+ add_filter("> 0")
63
+ end
64
+ end
65
+ end
@@ -1,16 +1,15 @@
1
- module Constraints
1
+ # = Constraints
2
+ # A custom set of constraints that can be applied
3
+ # to a query
4
+ module Relata::Dsl::Constraints
2
5
 
6
+ # Return all objects which fields by size
7
+ # Post.where { body.length < 22 }
3
8
  def length
4
9
  @relation_search = LengthManager
5
10
  self
6
11
  end
7
12
 
8
- class LengthManager
9
- def self.condition(field, *args)
10
- "len(field)"
11
- end
12
- end
13
-
14
13
  def count
15
14
  @select_fields << "COUNT(#{@current_field}.id) AS count"
16
15
  @groups << "#{table_name}.id"
@@ -18,9 +17,17 @@ module Constraints
18
17
  self
19
18
  end
20
19
 
20
+ # Return all objects which match with parameter
21
+ # Post.where(:body).like?("%caelum%")
21
22
  def like?(value)
22
23
  query.where("#{@current_field} like ?", [value])
23
24
  end
25
+
26
+ # Return all objects whith nil value fields
27
+ # Post.where(:body).is_null
28
+ def is_null
29
+ query.where("#{@current_field} is NULL")
30
+ end
24
31
 
25
32
  # def between(first, second)
26
33
  # @relation_search = SimpleRangeCondition
@@ -29,6 +36,12 @@ module Constraints
29
36
  # # add_filter("> #{first}").add_filter("< #{second}")
30
37
  # end
31
38
 
39
+ class LengthManager
40
+ def self.condition(field, *args)
41
+ "len(field)"
42
+ end
43
+ end
44
+
32
45
  class SimpleCondition
33
46
  def self.condition(field, *args)
34
47
  "#{field}"
@@ -0,0 +1,44 @@
1
+ # defines helper methods to deal with custom relation
2
+ module Relata::Dsl::CustomRelation
3
+ include Relata::Dsl::Conditions
4
+ include Relata::Dsl::Constraints
5
+
6
+ def using(record, field)
7
+ @record = record
8
+ @current_field = field
9
+ @start_field = field
10
+ @select_fields = ["#{table_name}.*"]
11
+ @groups = []
12
+
13
+ if relates_to_many?
14
+ self.extend MultipleQuery
15
+ self.extend ModelFields
16
+ elsif relates_belongs_to?
17
+ self.extend BelongsToQuery
18
+ self.extend ModelFields
19
+ else
20
+ self.extend SimpleQuery
21
+ end
22
+
23
+ self
24
+ end
25
+
26
+ def relates_to_many?
27
+ @record.reflect_on_all_associations.each do |r|
28
+ if r.name.to_sym.eql? @current_field.to_sym
29
+ return true if r.macro.to_s.eql? "has_many"
30
+ end
31
+ end
32
+ false
33
+ end
34
+
35
+ def relates_belongs_to?
36
+ @record.reflect_on_all_associations.each do |r|
37
+ if r.name.to_sym.eql? @current_field.to_sym
38
+ return true if r.macro.to_s.eql? "belongs_to"
39
+ end
40
+ end
41
+ false
42
+ end
43
+
44
+ end
@@ -0,0 +1,111 @@
1
+ # = Field Search
2
+ # a relation search in a specific field
3
+ class Relata::Dsl::FieldSearch
4
+
5
+ def initialize(rel, field)
6
+ @rel = rel
7
+ @field = field
8
+ end
9
+
10
+ # Exactly number of relation or field value
11
+ # Post.where { body == "CaelumObjects training and inovation" }
12
+ # Post.where { comments == 2 }
13
+ def ==(value)
14
+ @rel.where("#{@field} == ?", value)
15
+ end
16
+
17
+ # All records with different field value
18
+ # Post.where { comments == 2 }
19
+ def !=(value)
20
+ @rel.where("#{@field} <> ?", value)
21
+ end
22
+
23
+ # All records with higher or equal number of relations
24
+ # Post.where { comments >= 2 }
25
+ def >=(value)
26
+ @rel.where("#{@field} >= ?", value)
27
+ end
28
+
29
+ # All records with less or equal number of relations
30
+ # Post.where { comments <= 2 }
31
+ def <=(value)
32
+ @rel.where("#{@field} <= ?", value)
33
+ end
34
+
35
+ # All records with higher number of relations
36
+ # Post.where { comments > 2 }
37
+ def >(value)
38
+ @rel.where("#{@field} > ?", value)
39
+ end
40
+
41
+ # All records with lesser number of relations
42
+ # Post.where { comments < 2 }
43
+ def <(value)
44
+ @rel.where("#{@field} < ?", value)
45
+ end
46
+
47
+ # Find records by field value
48
+ # Post.where(:body).like?("%caelum%")
49
+ def like?(value)
50
+ @rel.where(@field).like?(value)
51
+ end
52
+
53
+ # Find record with date between
54
+ # Post.where { published_at.between(2.years.ago, 6.months.ago) }
55
+ def between(first, second)
56
+ @rel.where("#{@field} > ? and #{@field} < ?", first, second)
57
+ end
58
+
59
+ # Find records by size
60
+ # Post.where { body.length < 22 }
61
+ def length
62
+ @field = "length(#{@field})"
63
+ self
64
+ end
65
+
66
+ # Your custom relation
67
+ # Post.where { body "like ?", "%lum%" }
68
+ def custom(*args)
69
+ comparison = args.shift
70
+ @rel.where("#{@field} #{comparison}", args)
71
+ end
72
+
73
+ end
74
+
75
+ class Relata::Dsl::FieldSearchMany
76
+
77
+ def initialize(rel, field)
78
+ @rel = rel
79
+ @field = field
80
+ end
81
+
82
+ def ==(value)
83
+ @rel.where(@field).count.eq(value)
84
+ end
85
+
86
+ def >=(value)
87
+ @rel.where(@field).count.ge(value)
88
+ end
89
+
90
+ def <=(value)
91
+ @rel.where(@field).count.le(value)
92
+ end
93
+
94
+ def >(value)
95
+ @rel.where(@field).count.gt(value)
96
+ end
97
+
98
+ def <(value)
99
+ @rel.where(@field).count.lt(value)
100
+ end
101
+
102
+ def exists?
103
+ @rel.where(@field).exists?
104
+ end
105
+
106
+ def custom(*args)
107
+ comparison = args.shift
108
+ @rel.where("#{@field} #{comparison}", args)
109
+ end
110
+
111
+ end
@@ -0,0 +1,28 @@
1
+ # a builder ready to collect which field you want to search
2
+ class Relata::Dsl::MissedBuilder
3
+
4
+ def initialize(rel)
5
+ @rel = rel
6
+ end
7
+
8
+ def method_missing(field, *args)
9
+ relation = @rel.scoped
10
+ relation.extend Relata::Dsl::CustomRelation
11
+ relation.using(@rel, field)
12
+
13
+ if relation.relates_to_many?
14
+ type = Relata::Dsl::FieldSearchMany
15
+ else
16
+ type = Relata::Dsl::FieldSearch
17
+ end
18
+
19
+ instance = type.new(relation, field)
20
+
21
+ if args.size != 0
22
+ instance = instance.custom(*args)
23
+ end
24
+
25
+ instance
26
+ end
27
+
28
+ end
@@ -0,0 +1,8 @@
1
+ module BelongsToQuery
2
+ def query
3
+ preload(@start_field).select(@select_fields.join ',').from("#{table_name}, #{@start_field.to_s.pluralize}").where("#{table_name}.#{@start_field}_id = #{@start_field.to_s.pluralize}.id")
4
+ end
5
+ def add_filter expectation
6
+ query.group(@groups.first).having("#{@relation_search} #{expectation}")
7
+ end
8
+ end
@@ -1,13 +1,13 @@
1
1
  module ModelFields
2
2
 
3
3
  def self.extended(base)
4
-
4
+ @fields = []
5
5
  base.reflect_on_all_associations.each do |r|
6
- @fields = r.klass.columns.map do |c|
7
- c.name if [:string, :text].include? c.type
6
+ r.klass.columns.each do |c|
7
+ @fields << c.name if [:string, :text].include? c.type
8
8
  end
9
9
  end
10
-
10
+
11
11
  @fields.each do |field|
12
12
  include_method field if field != nil
13
13
  end
@@ -17,6 +17,11 @@ module ModelFields
17
17
  private
18
18
  def self.include_method(field)
19
19
  define_method field do
20
+
21
+ @record.reflect_on_all_associations.each do |r|
22
+ @current_field = @current_field.to_s.pluralize if r.macro.to_s.eql? "belongs_to"
23
+ end
24
+
20
25
  @current_field = "#{@current_field}.#{field}"
21
26
  self
22
27
  end
@@ -1,6 +1,26 @@
1
1
  require 'filtered_relation/related_query_methods'
2
2
  ActiveRecord::Base.send :include, RelatedQueryMethods
3
3
 
4
+
5
+ # = Filtered Relation
6
+ # Create dynamic filters with just onde method.
7
+
8
+ # <% form_tag :action => 'filter' do %>
9
+ # Title: <%= text_field_tag 'post[title]' %><br />
10
+ # Only with Comments?
11
+ # <%= select("post", "comments", options_for_select({ "false" => "", "true" => "true" })) %> %>
12
+ #
13
+ # def filter
14
+ # @posts = Post.filtered_relation(params[:post]).all
15
+ # end
16
+
17
+ # Create more advanced relations with DSL.
18
+
19
+ # posts = Post.filtered_relation(:comments => true).where(:user_id => 4).limit(3).order("id ASC") 



20
+
21
+ # posts.each do |post| 

22
+ # # records
23
+ # end 

4
24
  module FilteredRelation
5
25
 
6
26
  class ::ActiveRecord::Base
Binary file
@@ -1,6 +1,6 @@
1
1
  require File.expand_path(File.dirname(__FILE__)) + "/test_helper"
2
2
  require 'schema'
3
- require 'filtered_relation/dsl'
3
+ require 'relata/dsl'
4
4
 
5
5
  class DSLTest < ActiveSupport::TestCase
6
6
 
@@ -14,17 +14,17 @@ class DSLTest < ActiveSupport::TestCase
14
14
  posts = Post.where(:body).like?("%caelum%").all
15
15
  assert_equal @caelum, posts[0]
16
16
  assert_equal 1, posts.size
17
-
17
+
18
18
  posts = Post.where { body.like? "%caelum%" }
19
19
  assert_equal @caelum, posts[0]
20
20
  assert_equal 1, posts.size
21
21
  end
22
22
 
23
- # test "given an attribute and constraint expectation, gives the results" do
24
- # posts = Post.where { body < 22 }
25
- # assert_equal @guilherme, posts[0]
26
- # assert_equal 1, posts.size
27
- # end
23
+ test "given an attribute and constraint expectation, gives the results" do
24
+ posts = Post.where { body.length < 22 }
25
+ assert_equal @guilherme, posts[0]
26
+ assert_equal 1, posts.size
27
+ end
28
28
 
29
29
  test "exists posts with comments" do
30
30
  @caelum.update_attributes(:comments => [Comment.create])
@@ -38,7 +38,7 @@ class DSLTest < ActiveSupport::TestCase
38
38
  posts = Post.where(:comments).exists?
39
39
  assert_equal @caelum, posts[0]
40
40
  assert_equal 1, posts.size
41
-
41
+
42
42
  posts = Post.where { comments.exists? }
43
43
  assert_equal @caelum, posts[0]
44
44
  assert_equal 1, posts.size
@@ -61,64 +61,121 @@ class DSLTest < ActiveSupport::TestCase
61
61
  test "exists posts with more than or equals 2 comments" do
62
62
  @caelum.update_attributes(:comments => [Comment.create, Comment.create])
63
63
  @guilherme.update_attributes(:comments => [Comment.create, Comment.create, Comment.create])
64
-
65
- posts = Post.where(:comments).count.ge(2)
64
+
65
+ posts = Post.where(:comments).count.ge(2).all
66
+ assert_equal 2, posts.size
66
67
  assert_equal @caelum, posts[0]
67
68
  assert_equal @guilherme, posts[1]
68
- assert_equal 2, posts.size
69
69
  end
70
70
 
71
- test "all post which commits has some description" do
72
- comment = Comment.create :description => "dsl test"
73
- @caelum.update_attributes :comments => [comment]
74
-
75
- posts = Post.where(:comments).description.like?("%dsl test%")
76
- assert_equal @caelum, posts[0]
77
- assert_equal 1, posts.size
78
-
71
+ test "dsl query supports first" do
72
+ @caelum.update_attributes(:comments => [Comment.create, Comment.create])
73
+ @guilherme.update_attributes(:comments => [Comment.create, Comment.create, Comment.create])
74
+
75
+ posts = Post.where(:comments).count.ge(2).first
76
+ assert_equal @caelum, posts
79
77
  end
80
-
78
+
81
79
  test "exists posts using strict extended methods" do
82
80
  @caelum.update_attributes(:comments => [Comment.create, Comment.create])
83
81
  @guilherme.update_attributes(:comments => [Comment.create, Comment.create, Comment.create])
84
82
  posts = Post.where { comments >= 2 }
85
83
  assert_equal @caelum, posts[0]
84
+ assert_equal 2, posts.size
86
85
  assert_equal @guilherme, posts[1]
86
+ end
87
+
88
+ test "strict block supports first" do
89
+ @caelum.update_attributes(:comments => [Comment.create, Comment.create])
90
+ @guilherme.update_attributes(:comments => [Comment.create, Comment.create, Comment.create])
91
+ post = Post.where { comments >= 2 }.first
92
+ assert_equal @caelum, post
93
+ end
94
+
95
+ test "exists posts using range expectations" do
96
+ @caelum.update_attributes :published_at => 1.year.ago
97
+
98
+ posts = Post.where { published_at.between(2.years.ago, 6.months.ago) }
99
+ assert_equal @caelum, posts[0]
100
+ assert_equal 1, posts.size
101
+ end
102
+
103
+ test "accepts two conditions inline" do
104
+ @caelum.update_attributes :published_at => 1.year.ago
105
+ @guilherme.update_attributes :published_at => 1.year.ago
106
+
107
+ posts = Post.where {
108
+ published_at.between(2.years.ago, 6.months.ago)
109
+ body.like?("%lum%")
110
+ }
111
+ assert_equal @caelum, posts[0]
112
+ assert_equal 1, posts.size
113
+ end
114
+
115
+ test "supports two conditions in dsl mixing everything together" do
116
+ @caelum.update_attributes(:comments => [Comment.create, Comment.create])
117
+ @guilherme.update_attributes(:comments => [Comment.create, Comment.create, Comment.create])
118
+ posts = Post.where { comments >= 1 }.where(:body).like?("%lum%")
119
+ assert_equal @caelum, posts[0]
120
+ assert_equal 1, posts.size
121
+ end
122
+
123
+ test "supports == with relation count" do
124
+ @caelum.update_attributes(:comments => [Comment.create, Comment.create])
125
+ posts = Post.where { comments == 2 }
126
+ assert_equal @caelum, posts[0]
127
+ assert_equal 1, posts.size
128
+ end
129
+
130
+ test "supports == with simple field" do
131
+ posts = Post.where { body == "CaelumObjects training and inovation" }
132
+ assert_equal @caelum, posts[0]
133
+ assert_equal 1, posts.size
134
+ end
135
+
136
+ test "supports != with simple field" do
137
+ posts = Post.where { body != "diff" }
138
+ assert_equal @caelum, posts[0]
139
+ assert_equal @guilherme, posts[1]
87
140
  assert_equal 2, posts.size
88
141
  end
89
142
 
90
- test "exists posts using range expectations" do
143
+ test "accepts two conditions one after the other" do
91
144
  @caelum.update_attributes :published_at => 1.year.ago
145
+ @guilherme.update_attributes :published_at => 1.year.ago
92
146
 
93
147
  posts = Post.where { published_at.between(2.years.ago, 6.months.ago) }
94
148
  assert_equal @caelum, posts[0]
149
+ assert_equal 2, posts.size
150
+ posts = posts.where { body.like?("%lum%") }
151
+ assert_equal @caelum, posts[0]
95
152
  assert_equal 1, posts.size
96
153
  end
97
154
 
98
- test "all post which commits has some subject" do
99
- comment = Comment.create :subject => "dsl subject"
100
- @caelum.update_attributes :comments => [comment]
101
- posts = Post.where(:comments).subject.like?("%dsl subject%")
155
+ test "accepts any custom condition" do
156
+ posts = Post.where { body "like ?", "%lum%" }
102
157
  assert_equal @caelum, posts[0]
103
158
  assert_equal 1, posts.size
104
159
  end
105
-
106
- # test "exists posts aaaaaaaaaaaaa" do
107
- # @caelum.update_attributes :published_at => 1.year.ago
108
- #
109
- # posts = Post.where {
110
- # published_at.between(2.years.ago, 6.months.ago)
111
- # name.like?
112
- # }
160
+
161
+ test "give records with nil fields" do
162
+ @caelum.update_attributes :body => nil
163
+ posts = Post.where(:body).is_null
164
+ assert_equal @caelum, posts[0]
165
+ assert_equal 1, posts.size
166
+ end
167
+
168
+
169
+ # test "second level relation in a dsl" do
170
+ # comment = Comment.create :description => "dsl test"
171
+ # @caelum.update_attributes :comments => [comment]
172
+ #
173
+ # posts = Post.where{ comments.description.like?("%dsl test%") }
113
174
  # assert_equal @caelum, posts[0]
114
175
  # assert_equal 1, posts.size
176
+ #
115
177
  # end
116
178
 
117
- # def pending
118
- # support .all, .first, and so on
119
- # posts = Post.where { comments.description.like?("%dsl test%") }
120
- # posts = posts.and(:authors).count.lt(3)
121
179
  # Author.where(:posts).comments.count.gt(2)
122
- # end
123
-
180
+
124
181
  end
@@ -1,55 +1,55 @@
1
1
  require File.expand_path(File.dirname(__FILE__)) + "/test_helper"
2
2
 
3
- require 'filtered_relation/filter'
3
+ require 'relata/filter'
4
4
  require 'schema'
5
5
 
6
6
  class FilteredRelationTest < ActiveSupport::TestCase
7
7
  setup do
8
8
  setup_db
9
9
  create_posts
10
+ end
11
+
12
+ test "given no values to filtered_relation, gives us all records" do
13
+ assert_equal Post.all, Post.filtered_relation({}).all
14
+ end
15
+
16
+ test "given a content and comment filter, gives us filtered records - generic" do
17
+ @base.update_attributes(:content => "picture", :comments => [Comment.create])
18
+ assert_equal @base, Post.filtered_relation(:content => "picture", :comments => 'true').first
10
19
  end
11
20
 
12
- test "given no values to filtered_relation, gives us all records" do
13
- assert_equal Post.all, Post.filtered_relation({}).all
14
- end
15
-
16
- test "given a content and comment filter, gives us filtered records - generic" do
17
- @base.update_attributes(:content => "picture", :comments => [Comment.create])
18
- assert_equal @base, Post.filtered_relation(:content => "picture", :comments => 'true').first
19
- end
20
-
21
- test "given a content and comment filter, gives us filtered records" do
22
- @base.update_attributes(:content => "picture", :comments => [Comment.create])
23
- assert_equal @base, Post.filtered_relation(:content => "picture").related_to(:comments => true).first
24
- end
21
+ test "given a content and comment filter, gives us filtered records" do
22
+ @base.update_attributes(:content => "picture", :comments => [Comment.create])
23
+ assert_equal @base, Post.filtered_relation(:content => "picture").related_to(:comments => true).first
24
+ end
25
+
26
+ test "given a date and comment filter, gives us filtered records" do
27
+ @base.update_attributes(:published_at => 2.years.ago, :comments => [Comment.create])
28
+ assert_equal @base, Post.filtered_relation(:published_at => true).related_to(:comments => true).first
29
+ end
30
+
31
+ test "given a date and content filter, gives us filtered records" do
32
+ @base.update_attribute(:published_at, 2.years.ago)
33
+ @base.update_attribute(:content, "picture")
34
+ record = Post.filtered_relation(:published_at => true, :content => "picture").first
25
35
 
26
- test "given a date and comment filter, gives us filtered records" do
27
- @base.update_attributes(:published_at => 2.years.ago, :comments => [Comment.create])
28
- assert_equal @base, Post.filtered_relation(:published_at => true).related_to(:comments => true).first
29
- end
30
-
31
- test "given a date and content filter, gives us filtered records" do
32
- @base.update_attribute(:published_at, 2.years.ago)
33
- @base.update_attribute(:content, "picture")
34
- record = Post.filtered_relation(:published_at => true, :content => "picture").first
36
+ assert_equal @base, record
37
+ end
38
+
39
+ test "given two dates, gives us filtered records between this date" do
40
+ assert_equal @base, Post.date_between(:before => 1.year.ago, :after => Time.now).first
41
+ end
42
+
43
+ test "return a post with same title" do
44
+ @base.update_attributes(:title => "Post Title")
45
+ assert_equal @base, Post.filtered_relation(:title => "Post Title").first
46
+ end
47
+
48
+ test "return a post with same title and body" do
49
+ @base.update_attributes(:title => "Post Title", :body => "Ruby")
50
+ assert_equal @base, Post.filtered_relation(:title => "Post Title", :body => "Ruby").first
51
+ end
35
52
 
36
- assert_equal @base, record
37
- end
38
-
39
- test "given two dates, gives us filtered records between this date" do
40
- assert_equal @base, Post.date_between(:before => 1.year.ago, :after => Time.now).first
41
- end
42
-
43
- test "return a post with same title" do
44
- @base.update_attributes(:title => "Post Title")
45
- assert_equal @base, Post.filtered_relation(:title => "Post Title").first
46
- end
47
-
48
- test "return a post with same title and body" do
49
- @base.update_attributes(:title => "Post Title", :body => "Ruby")
50
- assert_equal @base, Post.filtered_relation(:title => "Post Title", :body => "Ruby").first
51
- end
52
-
53
53
 
54
54
  def create_posts
55
55
  valid_attributes = {
@@ -0,0 +1,57 @@
1
+ require File.expand_path(File.dirname(__FILE__)) + "/test_helper"
2
+ require 'schema'
3
+ require 'relata/dsl'
4
+
5
+ class DSLTest < ActiveSupport::TestCase
6
+
7
+ setup do
8
+ setup_db
9
+ @caelum = Post.create :body => "CaelumObjects training and inovation"
10
+ @guilherme = Post.create :body => "Guilherme Silveira"
11
+ end
12
+
13
+ test "all post which commits has some subject" do
14
+ comment = Comment.create :subject => "dsl subject"
15
+ @caelum.update_attributes :comments => [comment]
16
+ posts = Post.where(:comments).subject.like?("%dsl subject%")
17
+ assert_equal @caelum, posts[0]
18
+ assert_equal 1, posts.size
19
+ end
20
+
21
+ test "all post which commits has some description" do
22
+ comment = Comment.create :description => "dsl test"
23
+ @caelum.update_attributes :comments => [comment]
24
+
25
+ posts = Post.where(:comments).description.like?("%dsl test%")
26
+ assert_equal @caelum, posts[0]
27
+ assert_equal 1, posts.size
28
+
29
+ end
30
+
31
+ test "all post which commits has some subject and another has_many relation" do
32
+ reader = Reader.create :name => "anderson"
33
+ comment = Comment.create :subject => "dsl subject"
34
+ @caelum.update_attributes :comments => [comment], :readers => [reader]
35
+ posts = Post.where(:comments).subject.like?("%dsl subject%")
36
+ assert_equal @caelum, posts[0]
37
+ assert_equal 1, posts.size
38
+ end
39
+
40
+ test "exists posts for a specific user name" do
41
+ user = User.create :name => "anderson"
42
+ @caelum.update_attributes(:user => user)
43
+ posts = Post.where(:user).name.like?("anderson")
44
+ assert_equal @caelum, posts[0]
45
+ assert_equal 1, posts.size
46
+ end
47
+
48
+ test "exists posts for a specific user title" do
49
+ user = User.create :title => "programmer"
50
+ @caelum.update_attributes(:user => user)
51
+ posts = Post.where(:user).title.like?("programmer")
52
+ assert_equal @caelum, posts[0]
53
+ assert_equal 1, posts.size
54
+ end
55
+
56
+
57
+ end
@@ -20,6 +20,8 @@ def setup_db
20
20
  end
21
21
 
22
22
  create_table :users do |t|
23
+ t.string :name
24
+ t.text :title
23
25
  t.timestamps
24
26
  end
25
27
 
@@ -29,6 +31,13 @@ def setup_db
29
31
  t.integer :post_id
30
32
  t.timestamps
31
33
  end
34
+
35
+ create_table :readers do |t|
36
+ t.text :name
37
+ t.integer :post_id
38
+ t.timestamps
39
+ end
40
+
32
41
 
33
42
  end
34
43
  end
@@ -36,6 +45,7 @@ end
36
45
  class Post < ActiveRecord::Base
37
46
  belongs_to :user
38
47
  has_many :comments
48
+ has_many :readers
39
49
  end
40
50
 
41
51
  class User < ActiveRecord::Base
@@ -46,3 +56,7 @@ class Comment < ActiveRecord::Base
46
56
  belongs_to :post
47
57
  end
48
58
 
59
+ class Reader < ActiveRecord::Base
60
+ belongs_to :post
61
+ end
62
+
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 2
9
- version: 0.0.2
8
+ - 3
9
+ version: 0.0.3
10
10
  platform: ruby
11
11
  authors:
12
12
  - Anderson Leite, Guilherme Silveira
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-10-04 00:00:00 -03:00
17
+ date: 2010-10-05 00:00:00 -03:00
18
18
  default_executable:
19
19
  dependencies: []
20
20
 
@@ -35,17 +35,22 @@ files:
35
35
  - README.markdown
36
36
  - test.sqlite3
37
37
  - uninstall.rb
38
- - lib/filtered_relation/dsl/conditions.rb
39
- - lib/filtered_relation/dsl/constraints.rb
40
- - lib/filtered_relation/dsl/querys/fields.rb
41
- - lib/filtered_relation/dsl/querys/multiple.rb
42
- - lib/filtered_relation/dsl/querys/simple.rb
43
- - lib/filtered_relation/dsl.rb
44
- - lib/filtered_relation/filter.rb
45
- - lib/filtered_relation/related_query_methods.rb
46
- - lib/filtered_relation.rb
38
+ - lib/relata/dsl/conditions.rb
39
+ - lib/relata/dsl/constraints.rb
40
+ - lib/relata/dsl/custom_relation.rb
41
+ - lib/relata/dsl/field_search.rb
42
+ - lib/relata/dsl/missed_builder.rb
43
+ - lib/relata/dsl/querys/belongs.rb
44
+ - lib/relata/dsl/querys/fields.rb
45
+ - lib/relata/dsl/querys/multiple.rb
46
+ - lib/relata/dsl/querys/simple.rb
47
+ - lib/relata/dsl.rb
48
+ - lib/relata/filter.rb
49
+ - lib/relata/related_query_methods.rb
50
+ - lib/relata.rb
47
51
  - test/dsl_test.rb
48
52
  - test/filtered_relation_test.rb
53
+ - test/relation_dsl_test.rb
49
54
  - test/schema.rb
50
55
  - test/test_helper.rb
51
56
  has_rdoc: true
@@ -1,3 +0,0 @@
1
- module FilteredRelation
2
- require 'filtered_relation/filter'
3
- end
@@ -1,109 +0,0 @@
1
- require 'filtered_relation/dsl/conditions'
2
- require 'filtered_relation/dsl/constraints'
3
- require 'filtered_relation/dsl/querys/multiple'
4
- require 'filtered_relation/dsl/querys/simple'
5
- require 'filtered_relation/dsl/querys/fields'
6
-
7
- # in case you did not require the entire filtered_relation plugin
8
- module FilteredRelation
9
- module Dsl
10
- end
11
- end
12
-
13
- # defines helper methods to deal with custom relation
14
- module FilteredRelation::Dsl::CustomRelation
15
- include Conditions
16
- include Constraints
17
-
18
- def using(record, field)
19
- @record = record
20
- @current_field = field
21
- @start_field = field
22
- @select_fields = ["#{table_name}.*"]
23
- @groups = []
24
- if relates_to_many?
25
- self.extend MultipleQuery
26
- self.extend ModelFields
27
- else
28
- self.extend SimpleQuery
29
- end
30
-
31
- self
32
- end
33
-
34
- private
35
-
36
- def relates_to_many?
37
- @record.reflect_on_association @current_field.to_sym
38
- end
39
-
40
- end
41
-
42
- # a relation search in a specific field
43
- class FilteredRelation::Dsl::FieldSearch
44
-
45
- def initialize(rel, field)
46
- @rel = rel
47
- @field = field
48
- end
49
-
50
- def >=(value)
51
- @rel.where(@field).count.ge(value)
52
- end
53
-
54
- def like?(value)
55
- @rel.where(@field).like?(value)
56
- end
57
-
58
- def exists?
59
- @rel.where(@field).exists?
60
- end
61
-
62
- def between(first, second)
63
- @rel.where("#{@field} > ? and #{@field} < ?", first, second)
64
- end
65
-
66
- end
67
-
68
- # a builder ready to collect which field you want to search
69
- class FilteredRelation::Dsl::MissedBuilder
70
-
71
- def initialize(rel)
72
- @rel = rel
73
- end
74
-
75
- def method_missing(field, *args)
76
- if args.size != 0
77
- raise "Unable to setup a parameter with args: #{field} and #{args}"
78
- end
79
- FilteredRelation::Dsl::FieldSearch.new(@rel, field)
80
- end
81
-
82
- end
83
-
84
- module FilteredRelation::Dsl::Relation
85
-
86
- # extended where clause that allows symbol and custom dsl lookup
87
- #
88
- # examples:
89
- # where(:body).like?("%guilherme%")
90
- # where { body.like?("%guilherme%")
91
- #
92
- # While the last will delegate to the MissedBuilder component
93
- # the symbol based query will delegate query builder to CustomRelation.
94
- def where(*args, &block)
95
- if args.size==0 && block
96
- FilteredRelation::Dsl::MissedBuilder.new(self).instance_eval(&block)
97
- elsif args.size==1 && args[0].is_a?(Symbol)
98
- relation = scoped
99
- relation.extend FilteredRelation::Dsl::CustomRelation
100
- relation.using(self, args[0])
101
- else
102
- super(*args, &block)
103
- end
104
- end
105
- end
106
-
107
- class ActiveRecord::Relation
108
- include FilteredRelation::Dsl::Relation
109
- end
@@ -1,36 +0,0 @@
1
- # A custom set of conditions that can be applied
2
- # to a query
3
- module Conditions
4
- def ge(value)
5
- add_filter(">= #{value}")
6
- end
7
-
8
- def greater_or_equals(value)
9
- ge(value)
10
- end
11
-
12
- def gt(value)
13
- add_filter("> #{value}")
14
- end
15
-
16
- def greater_than(value)
17
- gt(value)
18
- end
19
-
20
- def lt(value)
21
- add_filter("< #{value}")
22
- end
23
-
24
- def lesser_than(value)
25
- lt value
26
- end
27
-
28
- # whether this relation has at least one element.
29
- def exists?
30
- if @relation_search.nil?
31
- count.exists?
32
- else
33
- add_filter("> 0")
34
- end
35
- end
36
- end