Permalink
Browse files

RelationalScope

this plugin lets you use scopes of child relations directly to filter
results instead of having to duplicate the scope conditions in multiple
places.  It handles conditions as best as possible for handling correct
table naming.

This is still a work in progress and not working currently.
  • Loading branch information...
0 parents commit eb6a8734f1276164b80748b6e42513e1bb47b91a @zacheryph committed Feb 20, 2009
Showing with 119 additions and 0 deletions.
  1. +20 −0 MIT-LICENSE
  2. +13 −0 README
  3. +23 −0 Rakefile
  4. +2 −0 init.rb
  5. +50 −0 lib/suid_bit/relational_scope.rb
  6. +8 −0 test/relational_scoping_test.rb
  7. +3 −0 test/test_helper.rb
@@ -0,0 +1,20 @@
+Copyright (c) 2009 Zachery Hostens <zacheryph@suidbit.com>
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,13 @@
+RelationalScope
+===============
+
+Introduction goes here.
+
+
+Example
+=======
+
+Example goes here.
+
+
+Copyright (c) 2009 Zachery Hostens, released under the MIT license
@@ -0,0 +1,23 @@
+require 'rake'
+require 'rake/testtask'
+require 'rake/rdoctask'
+
+desc 'Default: run unit tests.'
+task :default => :test
+
+desc 'Test the relational_scope plugin.'
+Rake::TestTask.new(:test) do |t|
+ t.libs << 'lib'
+ t.libs << 'test'
+ t.pattern = 'test/**/*_test.rb'
+ t.verbose = true
+end
+
+desc 'Generate documentation for the relational_scope plugin.'
+Rake::RDocTask.new(:rdoc) do |rdoc|
+ rdoc.rdoc_dir = 'rdoc'
+ rdoc.title = 'RelationalScope'
+ rdoc.options << '--line-numbers' << '--inline-source'
+ rdoc.rdoc_files.include('README')
+ rdoc.rdoc_files.include('lib/**/*.rb')
+end
@@ -0,0 +1,2 @@
+require 'suid_bit/relational_scope'
+ActiveRecord::Base.send :include, SuidBit::RelationalScope
@@ -0,0 +1,50 @@
+require 'active_record'
+
+module SuidBit
+ module RelationalScope
+ def self.included(klass)
+ klass.extend ClassMethods
+ end
+
+ module ClassMethods
+ def has_relational_scoping(relation, *args)
+ options = args.is_a?(Hash) ? args.pop : {}
+
+ klass = (options[:class_name] ? options[:class_name] : relation).to_s.classify.constantize
+ prefix = options[:prefix] or relation.to_s
+
+ klass.scopes.keys.each do |scope|
+ (class << self ; self end).instance_eval do
+ define_method "#{prefix}_#{scope}" do |*args|
+ with_relational_scope relation, klass, scope, options
+ end
+ end
+ end
+ end
+ end
+
+ protected
+ def with_relational_scope(relation, klass, scope, args)
+ options = klass.send(scope, *args).proxy_options
+
+ # need to setup the includes to properly link
+ case options[:include]
+ when Hash, Array
+ options[:include] = [{relation => options[:include]}]
+ when NilClass
+ options[:include] = [relation]
+ end
+
+ # conditions need to be string to ensure we get one query
+ # hash conditions with includes dont always join the table
+ # and the query crashes if conditions uses them
+ # so we take the time now to sanitize them into strings
+ case options[:conditions]
+ when Array ; options[:conditions] = sanitize_sql_array options[:conditions]
+ when Hash ; options[:conditions] = sanitize_sql_hash_for_conditions options[:conditions], klass.table_name
+ end
+
+ options
+ end
+ end
+end
@@ -0,0 +1,8 @@
+require 'test_helper'
+
+class RelationalScopeTest < ActiveSupport::TestCase
+ # Replace this with your real tests.
+ test "the truth" do
+ assert true
+ end
+end
@@ -0,0 +1,3 @@
+require 'rubygems'
+require 'active_support'
+require 'active_support/test_case'

0 comments on commit eb6a873

Please sign in to comment.