Add new finder methods to association collection.

This commit is contained in:
Pratik Naik
2009-12-27 00:21:24 +05:30
parent f374150698
commit 83f24afd44
7 changed files with 38 additions and 13 deletions

View File

@@ -1,5 +1,15 @@
*Edge*
* Add new finder methods to association collection. [Pratik Naik]
class User < ActiveRecord::Base
has_many :items
end
user = User.first
user.items.where(:items => {:colour => 'red'})
user.items.select('items.id')
* Add relation.reload to force reloading the records. [Pratik Naik]
topics = Topic.scoped

View File

@@ -1382,9 +1382,9 @@ module ActiveRecord
if reflection.through_reflection && reflection.source_reflection.belongs_to?
through = reflection.through_reflection
primary_key = reflection.source_reflection.primary_key_name
send(through.name).all(:select => "DISTINCT #{through.quoted_table_name}.#{primary_key}").map!(&:"#{primary_key}")
send(through.name).select("DISTINCT #{through.quoted_table_name}.#{primary_key}").map!(&:"#{primary_key}")
else
send(reflection.name).all(:select => "#{reflection.quoted_table_name}.#{reflection.klass.primary_key}").map!(&:id)
send(reflection.name).select("#{reflection.quoted_table_name}.#{reflection.klass.primary_key}").map!(&:id)
end
end
end

View File

@@ -20,7 +20,22 @@ module ActiveRecord
super
construct_sql
end
delegate :group, :order, :limit, :joins, :where, :preload, :eager_load, :to => :scoped
def select(select = nil, &block)
if block_given?
load_target
@target.select(&block)
else
scoped.select(select)
end
end
def scoped
with_scope(construct_scope) { @reflection.klass.scoped }
end
def find(*args)
options = args.extract_options!
@@ -383,7 +398,7 @@ module ActiveRecord
loaded if target
target
end
def method_missing(method, *args)
if @target.respond_to?(method) || (!@reflection.klass.respond_to?(method) && Class.respond_to?(method))
if block_given?

View File

@@ -221,9 +221,9 @@ module ActiveRecord
if new_record
association
elsif association.loaded?
autosave ? association : association.select { |record| record.new_record? }
autosave ? association : association.find_all { |record| record.new_record? }
else
autosave ? association.target : association.target.select { |record| record.new_record? }
autosave ? association.target : association.target.find_all { |record| record.new_record? }
end
end

View File

@@ -140,23 +140,23 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
def test_replace_order_is_preserved
posts(:welcome).people.clear
posts(:welcome).people = [people(:david), people(:michael)]
assert_equal [people(:david).id, people(:michael).id], posts(:welcome).readers.all(:order => 'id').map(&:person_id)
assert_equal [people(:david).id, people(:michael).id], posts(:welcome).readers.order('id').map(&:person_id)
# Test the inverse order in case the first success was a coincidence
posts(:welcome).people.clear
posts(:welcome).people = [people(:michael), people(:david)]
assert_equal [people(:michael).id, people(:david).id], posts(:welcome).readers.all(:order => 'id').map(&:person_id)
assert_equal [people(:michael).id, people(:david).id], posts(:welcome).readers.order('id').map(&:person_id)
end
def test_replace_by_id_order_is_preserved
posts(:welcome).people.clear
posts(:welcome).person_ids = [people(:david).id, people(:michael).id]
assert_equal [people(:david).id, people(:michael).id], posts(:welcome).readers.all(:order => 'id').map(&:person_id)
assert_equal [people(:david).id, people(:michael).id], posts(:welcome).readers.order('id').map(&:person_id)
# Test the inverse order in case the first success was a coincidence
posts(:welcome).people.clear
posts(:welcome).person_ids = [people(:michael).id, people(:david).id]
assert_equal [people(:michael).id, people(:david).id], posts(:welcome).readers.all(:order => 'id').map(&:person_id)
assert_equal [people(:michael).id, people(:david).id], posts(:welcome).readers.order('id').map(&:person_id)
end
def test_associate_with_create

View File

@@ -5,7 +5,7 @@ class EachTest < ActiveRecord::TestCase
fixtures :posts
def setup
@posts = Post.all(:order => "id asc")
@posts = Post.order("id asc")
@total = Post.count
end

View File

@@ -345,8 +345,8 @@ class NamedScopeTest < ActiveRecord::TestCase
def test_chaining_should_use_latest_conditions_when_searching
# Normal hash conditions
assert_equal Topic.all(:conditions => {:approved => true}).to_a, Topic.rejected.approved.all.to_a
assert_equal Topic.all(:conditions => {:approved => false}).to_a, Topic.approved.rejected.all.to_a
assert_equal Topic.where(:approved => true).to_a, Topic.rejected.approved.all.to_a
assert_equal Topic.where(:approved => false).to_a, Topic.approved.rejected.all.to_a
# Nested hash conditions with same keys
assert_equal [posts(:sti_comments)], Post.with_special_comments.with_very_special_comments.all.to_a