From af5e1b4cc6fd3ae5f5e175751373a5e60934385b Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Sun, 3 Jan 2010 19:42:29 +0530 Subject: Add Relation#except --- activerecord/CHANGELOG | 5 +++++ .../lib/active_record/relation/spawn_methods.rb | 22 ++++++++++++++++++++++ activerecord/test/cases/relations_test.rb | 12 ++++++++++++ 3 files changed, 39 insertions(+) (limited to 'activerecord') diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG index 4846774deb..0cfd8cdc87 100644 --- a/activerecord/CHANGELOG +++ b/activerecord/CHANGELOG @@ -1,5 +1,10 @@ *Edge* +* Add Relation#except. [Pratik Naik] + + one_red_item = Item.where(:colour => 'red').limit(1) + all_items = one_red_item.except(:where, :limit) + * Add Relation#delete_all. [Pratik Naik] Item.where(:colour => 'red').delete_all diff --git a/activerecord/lib/active_record/relation/spawn_methods.rb b/activerecord/lib/active_record/relation/spawn_methods.rb index 7b15279253..b9e3457aac 100644 --- a/activerecord/lib/active_record/relation/spawn_methods.rb +++ b/activerecord/lib/active_record/relation/spawn_methods.rb @@ -45,5 +45,27 @@ module ActiveRecord alias :& :merge + def except(*skips) + result = Relation.new(@klass, table) + result.table = table + + [:eager_load, :preload, :includes].each do |load_method| + result = result.send(load_method, send(:"#{load_method}_associations")) + end + + result.readonly = self.readonly unless skips.include?(:readonly) + + result = result.joins(@relation.joins(@relation)) unless skips.include?(:joins) + result = result.group(@relation.groupings) unless skips.include?(:group) + result = result.limit(@relation.taken) unless skips.include?(:limit) + result = result.offset(@relation.skipped) unless skips.include?(:offset) + result = result.select(@relation.send(:select_clauses)) unless skips.include?(:select) + result = result.from(@relation.sources) unless skips.include?(:from) + result = result.order(order_clause) unless skips.include?(:order) + result = result.where(*@relation.wheres) unless skips.include?(:where) + + result + end + end end diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb index 7046420ebd..bcecf74737 100644 --- a/activerecord/test/cases/relations_test.rb +++ b/activerecord/test/cases/relations_test.rb @@ -539,4 +539,16 @@ class RelationTest < ActiveRecord::TestCase assert ! hen.new_record? assert_equal 'hen', hen.name end + + def test_except + relation = Post.where(:author_id => 1).order('id ASC').limit(1) + assert_equal [posts(:welcome)], relation.all + + author_posts = relation.except(:order, :limit) + assert_equal Post.where(:author_id => 1).all, author_posts.all + + all_posts = relation.except(:where, :order, :limit) + assert_equal Post.all, all_posts.all + end + end -- cgit v1.2.3