has_finder 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,9 @@
1
- == 0.0.1 2007-08-26
1
+ == 0.1.0 2007-08-26
2
2
 
3
3
  * 1 major enhancement:
4
4
  * Initial release
5
+
6
+ == 0.1.2 2007-09-02
7
+
8
+ * Fix for protected with_scope (using send)
9
+ * README Documentation
data/README.txt CHANGED
@@ -1 +1,98 @@
1
- README
1
+ HasFinder is an extension to ActiveRecord that makes it easier than ever to create custom find and count queries.
2
+
3
+ Let's start with an example. Suppose you have an Article model; some articles are published, some are popular. Let's declare finders for each of these notions. You may be tempted to write something like the following:
4
+
5
+ class Article < ActiveRecord::Base
6
+ def self.published
7
+ find(:all, :conditions => {:published => true})
8
+ end
9
+
10
+ def self.popular
11
+ ...
12
+ end
13
+ ...
14
+ end
15
+
16
+ But there are serious limitations to this approach. How do you find articles that are BOTH popular and published? How can you easily paginate published articles?
17
+
18
+ # HasFinder Features
19
+
20
+ Let's define the equivalent finders using my new plugin, has_finder:
21
+
22
+ class Article < ActiveRecord::Base
23
+ has_finder :published, :conditions => {:published => true}
24
+ has_finder :popular, :conditions => ...
25
+ end
26
+
27
+ ## Query Composition
28
+
29
+ Now, you can elegantly compose queries:
30
+
31
+ Article.published.popular
32
+
33
+ This will return all articles that are both popular and published.
34
+
35
+ ## Calculations and Nested Finds
36
+ You can also easily paginate or call nested finders or do calculations:
37
+
38
+ Article.published.paginate(:page => 1)
39
+ Article.published.popular.count
40
+ Article.popular.find(:first)
41
+ Article.popular.find(:all, :conditions => {...})
42
+
43
+ ## Works with ActiveRecord `has_many` and `has_many :through` Associations
44
+ Furthermore, without any additional work, these finders will work with ActiveRecord associations.
45
+
46
+ class User
47
+ has_many :articles
48
+ end
49
+
50
+ user.articles.popular.find(:first)
51
+ user.articles.published.popular.average(:view_count)
52
+
53
+ ## Finders are extendable just like ActiveRecord Associations
54
+
55
+ class Article
56
+ has_finder :unpublished :conditions => {:published => false} do
57
+ def published_all
58
+ find(:all).map(&:publish)
59
+ end
60
+ end
61
+ end
62
+
63
+ Alternatively, you can use the :extend options:
64
+
65
+ class Article
66
+ has_finder :unpublished, :conditions => ..., :extend => MyExtensionModule
67
+ end
68
+
69
+ ## Finders behave just like ActiveRecord Associations
70
+
71
+ For example, you can call #reload:
72
+
73
+ Article.published.popular.reload
74
+
75
+ ## Finders can take parameters
76
+
77
+ class Car
78
+ has_finder :colored, lambda {|color| { :conditions => {:color => color} } }
79
+ end
80
+
81
+ Car.colored('red').paginate(:page => 1)
82
+
83
+ # What makes HasFinder better than alternatives like `scope_out` and `scoped_proxy`?
84
+
85
+ There are already two plugins similar to HasFinder: [`scope_out`](http://code.google.com/p/scope-out-rails) and [`scoped_proxy`](http://www.neotrivium.com/blog/2007/4/4/out_of_the_scope_of_scope_out?language=en-US). Both of them are excellent. In fact, Scoped Proxy was the model for HasFinder. Unfortunately, neither plugin provided all of the features I desired. Scope-Out lacks on-the-fly composition, a nice way to call a nested find, or the ability to do arbitrary calculations. Scoped Proxy is great, but it doesn't work with regular ActiveRecord Associations, it is not extendable like ActiveRecord associations, and it doesn't behave exactly like a regular ActiveRecord Association. Neither of them work out of the box with will_paginate. For all of these reasons and more, I rolled my own. It's now available as a gem.
86
+
87
+ # Installation
88
+
89
+ % gem install has_finder
90
+
91
+ # Usage
92
+
93
+ In environment.rb:
94
+
95
+ gem 'has_finder'
96
+ require 'has_finder'
97
+
98
+ See the examples above for usage.
@@ -25,7 +25,7 @@ module HasFinder
25
25
  elsif proxy_finder.finders.include?(method)
26
26
  finders[method].call(self, *args)
27
27
  else
28
- proxy_finder.with_scope :find => proxy_scope do
28
+ proxy_finder.send(:with_scope, { :find => proxy_scope }) do
29
29
  proxy_finder.send(method, *args, &block)
30
30
  end
31
31
  end
@@ -2,7 +2,7 @@ module HasFinder #:nodoc:
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
4
  MINOR = 1
5
- TINY = 1
5
+ TINY = 2
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
@@ -5818,3 +5818,97 @@ Spec::Rails::DSL::ViewExampleController: missing default helper path spec/rails/
5818
5818
  Property Load (0.000189) SELECT * FROM properties WHERE (properties.being_id = 2) 
5819
5819
  Property Load (0.000211) SELECT * FROM properties WHERE (( properties.being_id = 2 ) AND ( name LIKE 'r%' )) AND (properties.being_id = 2) 
5820
5820
  SQL (0.000097) ROLLBACK
5821
+ Spec::Rails::DSL::HelperEvalContextController: missing default helper path spec/rails/dsl/helper_eval_context_helper
5822
+ Spec::Rails::DSL::ViewExampleController: missing default helper path spec/rails/dsl/view_example_helper
5823
+ SQL (0.037990) SET SQL_AUTO_IS_NULL=0
5824
+ SQL (0.000119) BEGIN
5825
+ Being Load (0.004143) SELECT * FROM beings 
5826
+ Being Columns (0.013376) SHOW FIELDS FROM beings
5827
+ SQL (0.167181) INSERT INTO beings (`country`, `race`) VALUES(NULL, NULL)
5828
+ Being Load (0.000335) SELECT * FROM beings 
5829
+ Being Load (0.000250) SELECT * FROM beings 
5830
+ SQL (0.005772) ROLLBACK
5831
+ SQL (0.000080) BEGIN
5832
+ Being Load (0.000290) SELECT * FROM beings 
5833
+ Being Load (0.000245) SELECT * FROM beings 
5834
+ Being Load (0.000248) SELECT * FROM beings LIMIT 1
5835
+ Being Load (0.000225) SELECT * FROM beings LIMIT 1
5836
+ Being Load (0.000237) SELECT * FROM beings 
5837
+ SQL (0.033188) SELECT count(*) AS count_all FROM beings 
5838
+ SQL (0.000257) SELECT count(*) AS count_all FROM beings 
5839
+ Being Load (0.000259) SELECT * FROM beings 
5840
+ SQL (0.009529) SELECT avg(id) AS avg_id FROM beings 
5841
+ SQL (0.000269) SELECT avg(id) AS avg_id FROM beings 
5842
+ SQL (0.000165) ROLLBACK
5843
+ SQL (0.000415) BEGIN
5844
+ Being Load (0.000260) SELECT * FROM beings 
5845
+ Being Load (0.000217) SELECT * FROM beings 
5846
+ Being Load (0.000218) SELECT * FROM beings 
5847
+ Being Load (0.000220) SELECT * FROM beings 
5848
+ Being Load (0.000215) SELECT * FROM beings 
5849
+ Being Load (0.000213) SELECT * FROM beings 
5850
+ SQL (0.000145) ROLLBACK
5851
+ SQL (0.000084) BEGIN
5852
+ Being Load (0.001138) SELECT * FROM beings WHERE (beings.`country` = 'greece') 
5853
+ Being Load (0.000217) SELECT * FROM beings WHERE (beings.`id` = 1) 
5854
+ Being Load (0.000187) SELECT * FROM beings WHERE (beings.`id` = 3) 
5855
+ Being Load (0.000332) SELECT * FROM beings WHERE (beings.`race` = 'mortal') 
5856
+ Being Load (0.000200) SELECT * FROM beings WHERE (beings.`id` = 2) 
5857
+ SQL (0.000102) ROLLBACK
5858
+ SQL (0.000319) BEGIN
5859
+ Being Load (0.000223) SELECT * FROM beings WHERE (beings.`country` = 'greece') LIMIT 1
5860
+ Being Load (0.000192) SELECT * FROM beings WHERE (beings.`id` = 1) 
5861
+ SQL (0.000080) ROLLBACK
5862
+ SQL (0.000240) BEGIN
5863
+ Being Load (0.000213) SELECT * FROM beings WHERE (beings.`country` = 'greece') 
5864
+ Being Load (0.025420) SELECT * FROM beings WHERE (( ( beings.`country` = 'greece' ) AND ( beings.`race` = 'mortal' ) ) AND ( beings.`country` = 'greece' )) 
5865
+ Being Load (0.000303) SELECT * FROM beings WHERE (beings.`id` = 1) 
5866
+ SQL (0.000167) ROLLBACK
5867
+ SQL (0.000085) BEGIN
5868
+ Being Load (0.000283) SELECT * FROM beings WHERE (beings.`country` = 'greece') 
5869
+ Being Load (0.000189) SELECT * FROM beings WHERE (beings.`id` = 1) 
5870
+ Being Load (0.000168) SELECT * FROM beings WHERE (beings.`id` = 3) 
5871
+ Being Load (0.000197) SELECT * FROM beings WHERE (beings.`country` = 'greece') LIMIT 1
5872
+ SQL (0.000098) ROLLBACK
5873
+ SQL (0.000083) BEGIN
5874
+ SQL (0.000084) ROLLBACK
5875
+ SQL (0.000262) BEGIN
5876
+ SQL (0.000087) ROLLBACK
5877
+ SQL (0.000259) BEGIN
5878
+ SQL (0.000085) ROLLBACK
5879
+ SQL (0.000064) BEGIN
5880
+ Property Load (0.000361) SELECT * FROM properties WHERE (name LIKE 'r%') 
5881
+ Property Columns (0.001772) SHOW FIELDS FROM properties
5882
+ Property Load (0.000655) SELECT * FROM properties WHERE (properties.`id` = 1) 
5883
+ Property Load (0.000228) SELECT * FROM properties WHERE (properties.`id` = 2) 
5884
+ Property Load (0.000213) SELECT * FROM properties WHERE (properties.`id` = 3) 
5885
+ Being Load (0.000238) SELECT * FROM beings WHERE (beings.`id` = 2) 
5886
+ Property Load (0.000230) SELECT * FROM properties WHERE (properties.`id` = 4) 
5887
+ Property Load (0.000244) SELECT * FROM properties WHERE (properties.being_id = 2) 
5888
+ Property Load (0.000266) SELECT * FROM properties WHERE (( properties.being_id = 2 ) AND ( name LIKE 'r%' )) AND (properties.being_id = 2) 
5889
+ SQL (0.000145) ROLLBACK
5890
+ Spec::Rails::DSL::HelperEvalContextController: missing default helper path spec/rails/dsl/helper_eval_context_helper
5891
+ Spec::Rails::DSL::ViewExampleController: missing default helper path spec/rails/dsl/view_example_helper
5892
+ SQL (0.000138) SET SQL_AUTO_IS_NULL=0
5893
+ SQL (0.000109) BEGIN
5894
+ SQL (0.000169) ROLLBACK
5895
+ SQL (0.000179) BEGIN
5896
+ SQL (0.000168) ROLLBACK
5897
+ SQL (0.000319) BEGIN
5898
+ SQL (0.000166) ROLLBACK
5899
+ SQL (0.000179) BEGIN
5900
+ SQL (0.000163) ROLLBACK
5901
+ SQL (0.000299) BEGIN
5902
+ SQL (0.000187) ROLLBACK
5903
+ SQL (0.000328) BEGIN
5904
+ SQL (0.000173) ROLLBACK
5905
+ SQL (0.000124) BEGIN
5906
+ SQL (0.000191) ROLLBACK
5907
+ SQL (0.000179) BEGIN
5908
+ SQL (0.000071) ROLLBACK
5909
+ SQL (0.000246) BEGIN
5910
+ SQL (0.000073) ROLLBACK
5911
+ SQL (0.000201) BEGIN
5912
+ SQL (0.000072) ROLLBACK
5913
+ SQL (0.000146) BEGIN
5914
+ SQL (0.000179) ROLLBACK
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.0
3
3
  specification_version: 1
4
4
  name: has_finder
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.1.1
7
- date: 2007-08-26 00:00:00 -07:00
6
+ version: 0.1.2
7
+ date: 2007-09-02 00:00:00 -07:00
8
8
  summary: description of gem
9
9
  require_paths:
10
10
  - lib