Relata 0.0.2

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/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source :gemcutter
2
+ gem 'sqlite3-ruby', :require => 'sqlite3'
3
+ gem 'ruby-debug19', :require => "ruby-debug"
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 [name of plugin creator]
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.markdown ADDED
@@ -0,0 +1,43 @@
1
+ #FilteredRelation#
2
+
3
+ Making dynamic filters easier with a nice ActiveRecord DSL.
4
+
5
+ ## Filter Example ##
6
+
7
+ Create dynamic filters with just onde method.
8
+
9
+ <% form_tag :action => 'filter' do %>
10
+ Title: <%= text_field_tag 'post[title]' %><br />
11
+ Only with Comments?
12
+ <%= select("post", "comments", options_for_select({ "false" => "", "true" => "true" })) %> %>
13
+
14
+ def filter
15
+ @posts = Post.filtered_relation(params[:post]).all
16
+ end
17
+
18
+ Create more advanced relations.
19
+
20
+ posts = Post.filtered_relation(:comments => true).where(:user_id => 4).limit(3).order("id ASC") 



21
+
22
+ posts.each do |post| 

23
+ # records
24
+ end 

25
+
26
+ ## DSL API ##
27
+
28
+ Post.where(:body).like?("%caelum%")
29
+
30
+ Post.where(:comments).count.exists?
31
+
32
+ Post.where(:comments).count.gt(2)
33
+
34
+ Post.where(:comments).count.lt(2)
35
+
36
+ Post.where(:comments).description.like?("%filtered%")
37
+
38
+ Post.where(:comments).subject.like?("%filtered%")
39
+
40
+ Post.where { comments >= 2 }
41
+
42
+ Post.where { published_at.between(2.years.ago, 6.months.ago) }
43
+
data/Rakefile ADDED
@@ -0,0 +1,45 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+ require 'rake/gempackagetask'
5
+
6
+ desc 'Default: run unit tests.'
7
+ task :default => :test
8
+
9
+ desc 'Test the relata plugin.'
10
+ Rake::TestTask.new(:test) do |t|
11
+ t.libs << 'lib'
12
+ t.libs << 'test'
13
+ t.pattern = 'test/**/*_test.rb'
14
+ t.verbose = true
15
+ end
16
+
17
+ desc 'Generate documentation for the relata plugin.'
18
+ Rake::RDocTask.new(:rdoc) do |rdoc|
19
+ rdoc.rdoc_dir = 'rdoc'
20
+ rdoc.title = 'Relata'
21
+ rdoc.options << '--line-numbers' << '--inline-source'
22
+ rdoc.rdoc_files.include('README.markdown')
23
+ rdoc.rdoc_files.include('lib/**/*.rb')
24
+ end
25
+
26
+ PKG_FILES = FileList[ '[a-zA-Z]*', 'generators/**/*', 'lib/**/*', 'rails/**/*', 'tasks/**/*', 'test/**/*' ]
27
+
28
+ spec = Gem::Specification.new do |s|
29
+ s.name = "Relata"
30
+ s.version = "0.0.2"
31
+ s.author = "Anderson Leite, Guilherme Silveira"
32
+ s.email = "anderson.leite@caelum.com.br"
33
+ s.homepage = "http://github.com/caelum/relata"
34
+ s.platform = Gem::Platform::RUBY
35
+ s.summary = "Helps poking around with relationships when using ARel"
36
+ s.files = PKG_FILES.to_a
37
+ s.require_path = "lib"
38
+ s.has_rdoc = false
39
+ s.extra_rdoc_files = ["README.markdown"]
40
+ end
41
+
42
+ desc 'Turn this plugin into a gem.'
43
+ Rake::GemPackageTask.new(spec) do |pkg|
44
+ pkg.gem_spec = spec
45
+ end
data/init.rb ADDED
@@ -0,0 +1,7 @@
1
+ $:.unshift(File.join(File.dirname(__FILE__), "lib"))
2
+
3
+ require 'ruby-debug'
4
+ require 'active_record'
5
+ require "active_support"
6
+
7
+ require "filtered_relation"
data/install.rb ADDED
@@ -0,0 +1 @@
1
+ # Install hook code here
@@ -0,0 +1,36 @@
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
@@ -0,0 +1,62 @@
1
+ module Constraints
2
+
3
+ def length
4
+ @relation_search = LengthManager
5
+ self
6
+ end
7
+
8
+ class LengthManager
9
+ def self.condition(field, *args)
10
+ "len(field)"
11
+ end
12
+ end
13
+
14
+ def count
15
+ @select_fields << "COUNT(#{@current_field}.id) AS count"
16
+ @groups << "#{table_name}.id"
17
+ @relation_search = 'count'
18
+ self
19
+ end
20
+
21
+ def like?(value)
22
+ query.where("#{@current_field} like ?", [value])
23
+ end
24
+
25
+ # def between(first, second)
26
+ # @relation_search = SimpleRangeCondition
27
+ # self
28
+ # # query.where("#{@current_field} like ?", [value])
29
+ # # add_filter("> #{first}").add_filter("< #{second}")
30
+ # end
31
+
32
+ class SimpleCondition
33
+ def self.condition(field, *args)
34
+ "#{field}"
35
+ end
36
+ end
37
+
38
+ class SimpleRangeCondition
39
+ def self.condition(field, *args)
40
+ "#{field} > #{args[0]} AND #{field} < #{args[1]}"
41
+ end
42
+ end
43
+
44
+ class RangeManager
45
+ def self.select_fields(facet)
46
+ "COUNT(#{facet}.id) AS count"
47
+ end
48
+ def self.having(expectation)
49
+ "count #{expectation}"
50
+ end
51
+ end
52
+
53
+ class CountManager
54
+ def self.select_fields(facet)
55
+ "COUNT(#{facet}.id) AS count"
56
+ end
57
+ def self.having(expectation)
58
+ "count #{expectation}"
59
+ end
60
+ end
61
+
62
+ end
@@ -0,0 +1,25 @@
1
+ module ModelFields
2
+
3
+ def self.extended(base)
4
+
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
8
+ end
9
+ end
10
+
11
+ @fields.each do |field|
12
+ include_method field if field != nil
13
+ end
14
+
15
+ end
16
+
17
+ private
18
+ def self.include_method(field)
19
+ define_method field do
20
+ @current_field = "#{@current_field}.#{field}"
21
+ self
22
+ end
23
+ end
24
+
25
+ end
@@ -0,0 +1,8 @@
1
+ module MultipleQuery
2
+ def query
3
+ preload(@start_field).select(@select_fields.join ',').from("#{table_name}, #{@start_field}").where("#{table_name}.id = #{@start_field}.post_id")
4
+ end
5
+ def add_filter expectation
6
+ query.group(@groups.first).having("#{@relation_search} #{expectation}")
7
+ end
8
+ end
@@ -0,0 +1,11 @@
1
+ module SimpleQuery
2
+ def query
3
+ self
4
+ end
5
+
6
+ def add_filter *expectation
7
+ base = @relation_search.condition(@current_field.to_s, expectation)
8
+ where("#{base} #{expectation}")
9
+ end
10
+
11
+ end
@@ -0,0 +1,109 @@
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
@@ -0,0 +1,46 @@
1
+ require 'filtered_relation/related_query_methods'
2
+ ActiveRecord::Base.send :include, RelatedQueryMethods
3
+
4
+ module FilteredRelation
5
+
6
+ class ::ActiveRecord::Base
7
+
8
+ def self.filtered_relation(params)
9
+ relation = scoped
10
+
11
+ columns = self.columns.map do |c|
12
+ c.name if [:string, :text].include? c.type
13
+ end
14
+
15
+ params.each do |facet, value|
16
+ if self.reflect_on_association facet.to_sym
17
+ relation = send("filter_by_has_many", facet, value, relation)
18
+ elsif columns.include? facet.to_s
19
+ relation = send("filter_by_exact", facet, value, relation)
20
+ else
21
+ relation = send("filter_by_#{facet}", value, relation)
22
+ end
23
+ end
24
+
25
+ relation
26
+ end
27
+
28
+ def self.related_to(params)
29
+ relation = scoped
30
+
31
+ params.each do |facet, value|
32
+ relation = send("filter_by_related", facet, value, relation)
33
+ end
34
+ relation
35
+ end
36
+
37
+ def self.date_between(params)
38
+ relation = scoped
39
+ relation = send("filter_by_date_between", params, relation)
40
+ relation
41
+ end
42
+
43
+
44
+ end
45
+
46
+ end
@@ -0,0 +1,44 @@
1
+ module RelatedQueryMethods
2
+
3
+ def self.included(base)
4
+ base.extend ClassMethods
5
+ end
6
+
7
+ module ClassMethods
8
+
9
+ def filter_by_has_many(facet, value, relation)
10
+
11
+ table_name = self.table_name
12
+
13
+ if !value.empty?
14
+ relation.preload(facet).select("#{table_name}.*, COUNT(#{facet}.id) AS count").from("#{table_name}, #{facet}").where("#{table_name}.id = #{facet}.post_id").group("#{table_name}.id").having("count > 0")
15
+ else
16
+ relation
17
+ end
18
+ end
19
+
20
+ def filter_by_related(facet, value, relation)
21
+ if value
22
+ relation.preload(facet).select("posts.*, COUNT(#{facet}.id) AS comment_count").from("posts, #{facet}").group("posts.id").having("comment_count > 0")
23
+ else
24
+ relation
25
+ end
26
+ end
27
+
28
+ def filter_by_exact(facet, value, relation)
29
+ !value.empty? ? relation.where(facet => value) : relation
30
+ end
31
+
32
+ def filter_by_published_at(value, relation)
33
+ value ? relation.where("published_at < ?", 1.month.ago) : relation
34
+ end
35
+
36
+ def filter_by_date_between(params, relation)
37
+ relation.where("published_at < ?", params[:before])
38
+ relation.where("published_at > ?", params[:after])
39
+ relation
40
+ end
41
+
42
+ end
43
+
44
+ end
@@ -0,0 +1,3 @@
1
+ module FilteredRelation
2
+ require 'filtered_relation/filter'
3
+ end
data/test/dsl_test.rb ADDED
@@ -0,0 +1,124 @@
1
+ require File.expand_path(File.dirname(__FILE__)) + "/test_helper"
2
+ require 'schema'
3
+ require 'filtered_relation/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 "given an attribute and expectation, gives the results" do
14
+ posts = Post.where(:body).like?("%caelum%").all
15
+ assert_equal @caelum, posts[0]
16
+ assert_equal 1, posts.size
17
+
18
+ posts = Post.where { body.like? "%caelum%" }
19
+ assert_equal @caelum, posts[0]
20
+ assert_equal 1, posts.size
21
+ end
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
28
+
29
+ test "exists posts with comments" do
30
+ @caelum.update_attributes(:comments => [Comment.create])
31
+ posts = Post.where(:comments).count.exists?
32
+ assert_equal @caelum, posts[0]
33
+ assert_equal 1, posts.size
34
+ end
35
+
36
+ test "exists posts with comments can be shortcuted with exists?" do
37
+ @caelum.update_attributes(:comments => [Comment.create])
38
+ posts = Post.where(:comments).exists?
39
+ assert_equal @caelum, posts[0]
40
+ assert_equal 1, posts.size
41
+
42
+ posts = Post.where { comments.exists? }
43
+ assert_equal @caelum, posts[0]
44
+ assert_equal 1, posts.size
45
+ end
46
+
47
+ test "exists posts with more than 2 comments" do
48
+ @caelum.update_attributes(:comments => [Comment.create, Comment.create, Comment.create])
49
+ posts = Post.where(:comments).count.gt(2)
50
+ assert_equal @caelum, posts.first
51
+ assert_equal 3, posts.first.comments.size
52
+ end
53
+
54
+ test "exists posts with less than 2 comments" do
55
+ @caelum.update_attributes(:comments => [Comment.create])
56
+ posts = Post.where(:comments).count.lt(2)
57
+ assert_equal @caelum, posts.first
58
+ assert_equal 1, posts.first.comments.size
59
+ end
60
+
61
+ test "exists posts with more than or equals 2 comments" do
62
+ @caelum.update_attributes(:comments => [Comment.create, Comment.create])
63
+ @guilherme.update_attributes(:comments => [Comment.create, Comment.create, Comment.create])
64
+
65
+ posts = Post.where(:comments).count.ge(2)
66
+ assert_equal @caelum, posts[0]
67
+ assert_equal @guilherme, posts[1]
68
+ assert_equal 2, posts.size
69
+ end
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
+
79
+ end
80
+
81
+ test "exists posts using strict extended methods" do
82
+ @caelum.update_attributes(:comments => [Comment.create, Comment.create])
83
+ @guilherme.update_attributes(:comments => [Comment.create, Comment.create, Comment.create])
84
+ posts = Post.where { comments >= 2 }
85
+ assert_equal @caelum, posts[0]
86
+ assert_equal @guilherme, posts[1]
87
+ assert_equal 2, posts.size
88
+ end
89
+
90
+ test "exists posts using range expectations" do
91
+ @caelum.update_attributes :published_at => 1.year.ago
92
+
93
+ posts = Post.where { published_at.between(2.years.ago, 6.months.ago) }
94
+ assert_equal @caelum, posts[0]
95
+ assert_equal 1, posts.size
96
+ end
97
+
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%")
102
+ assert_equal @caelum, posts[0]
103
+ assert_equal 1, posts.size
104
+ 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
+ # }
113
+ # assert_equal @caelum, posts[0]
114
+ # assert_equal 1, posts.size
115
+ # end
116
+
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
+ # Author.where(:posts).comments.count.gt(2)
122
+ # end
123
+
124
+ end
@@ -0,0 +1,75 @@
1
+ require File.expand_path(File.dirname(__FILE__)) + "/test_helper"
2
+
3
+ require 'filtered_relation/filter'
4
+ require 'schema'
5
+
6
+ class FilteredRelationTest < ActiveSupport::TestCase
7
+ setup do
8
+ setup_db
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
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
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
35
+
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
+
54
+ def create_posts
55
+ valid_attributes = {
56
+ :body => "Hello.",
57
+ :title => "Hi!",
58
+ :content => "text",
59
+ :user_id => 1,
60
+ :published_at => Time.now
61
+ }
62
+
63
+ @base = Post.create(valid_attributes)
64
+ @quote = Post.create(valid_attributes.merge(:content => "quote"))
65
+ @number2 = Post.create(valid_attributes.merge(:user_id => 2))
66
+ @old = Post.create(valid_attributes.merge(:published_at => 1.year.ago))
67
+ end
68
+
69
+ teardown do
70
+ ActiveRecord::Base.connection.tables.each do |table|
71
+ ActiveRecord::Base.connection.drop_table(table)
72
+ end
73
+ end
74
+
75
+ end
data/test/schema.rb ADDED
@@ -0,0 +1,48 @@
1
+ require 'active_record'
2
+
3
+ ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => "test.sqlite3")
4
+
5
+ def setup_db
6
+
7
+ ActiveRecord::Base.connection.tables.each do |table|
8
+ ActiveRecord::Base.connection.drop_table(table)
9
+ end
10
+
11
+ ActiveRecord::Schema.define(:version => 1) do
12
+
13
+ create_table :posts do |t|
14
+ t.string :body
15
+ t.string :title
16
+ t.text :content
17
+ t.integer :user_id
18
+ t.datetime :published_at
19
+ t.timestamps
20
+ end
21
+
22
+ create_table :users do |t|
23
+ t.timestamps
24
+ end
25
+
26
+ create_table :comments do |t|
27
+ t.text :subject
28
+ t.text :description
29
+ t.integer :post_id
30
+ t.timestamps
31
+ end
32
+
33
+ end
34
+ end
35
+
36
+ class Post < ActiveRecord::Base
37
+ belongs_to :user
38
+ has_many :comments
39
+ end
40
+
41
+ class User < ActiveRecord::Base
42
+ has_many :posts
43
+ end
44
+
45
+ class Comment < ActiveRecord::Base
46
+ belongs_to :post
47
+ end
48
+
@@ -0,0 +1,3 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'active_support'
data/test.sqlite3 ADDED
Binary file
data/uninstall.rb ADDED
@@ -0,0 +1 @@
1
+ # Uninstall hook code here
metadata ADDED
@@ -0,0 +1,84 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: Relata
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 2
9
+ version: 0.0.2
10
+ platform: ruby
11
+ authors:
12
+ - Anderson Leite, Guilherme Silveira
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-10-04 00:00:00 -03:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description:
22
+ email: anderson.leite@caelum.com.br
23
+ executables: []
24
+
25
+ extensions: []
26
+
27
+ extra_rdoc_files:
28
+ - README.markdown
29
+ files:
30
+ - Gemfile
31
+ - init.rb
32
+ - install.rb
33
+ - MIT-LICENSE
34
+ - Rakefile
35
+ - README.markdown
36
+ - test.sqlite3
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
47
+ - test/dsl_test.rb
48
+ - test/filtered_relation_test.rb
49
+ - test/schema.rb
50
+ - test/test_helper.rb
51
+ has_rdoc: true
52
+ homepage: http://github.com/caelum/relata
53
+ licenses: []
54
+
55
+ post_install_message:
56
+ rdoc_options: []
57
+
58
+ require_paths:
59
+ - lib
60
+ required_ruby_version: !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ segments:
66
+ - 0
67
+ version: "0"
68
+ required_rubygems_version: !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ segments:
74
+ - 0
75
+ version: "0"
76
+ requirements: []
77
+
78
+ rubyforge_project:
79
+ rubygems_version: 1.3.7
80
+ signing_key:
81
+ specification_version: 3
82
+ summary: Helps poking around with relationships when using ARel
83
+ test_files: []
84
+