Skip to content

Commit

Permalink
Added the ability to pass a block to the familytree_v2.person method.…
Browse files Browse the repository at this point in the history
… If requesting an array of person ids, the block will be passed an array of person objects immediately after each HTTP call. For example, if 25 person ids are requested, the block will be executed 3 times, once with the first 10 persons, again with the next 10, and the next time with the last 5.
  • Loading branch information
jimmyz committed May 14, 2010
1 parent 1df9fa5 commit d811d72
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 3 deletions.
26 changes: 25 additions & 1 deletion README.rdoc
Expand Up @@ -62,10 +62,34 @@ or for the pure Ruby implementation
puts "First spouse's gender: " + person.families[0].parents[1].gender
puts "First spouse's ID: " + person.families[0].parents[1].id

# read multiple persons in one request (up to 10)
# Read multiple persons in one request.
# You can request as many person records as needed. The communicator will
# check the person.max.ids property from the /familytree/v2/properties call
# and will automatically break the array into appropriate slices, then return the whole.
people = communicator.familytree_v2.person ['KW3B-NNM','KWQS-BBQ','KWQS-BBR'], :parents => 'all', :children => 'all', :families => 'all'
people.size #=> 3

# Ruby blocks:
# You can pass a block to the person read that will be executed for each person
# or set of persons immediately after they are read. This is useful if you want to
# create a progress indicator if you are requesting a very large array of persons.
ids = ['KWCZ-1WL','KWCH-DGY','KWZR-RPD','KWCH-DPM','KWCH-DP9',
'KN1H-HBK','KLYL-KPZ','2794-46L','279W-NDV','KWJJ-5Y3','26KN-QTT',
'KWCV-7F7','2NQ9-FGV','K2WM-SHZ','KCR4-MBW','KWZR-RPX']
# because we are passing 16 ids, this will require 2 person reads (10 persons each read)
# the block will be called twice with the persons in each batch passed
progress_count = 0
communicator.familytree_v2.person ids do |persons|
progress_count += persons.size
puts progress_count
end

# if a single ID is passed, then the block will receive a single person, not an array
# of persons
communicator.familytree_v2.person :me do |person|
puts person.id
end

=== Searching Records

search = communicator.familytree_v2.search :givenName => "John",
Expand Down
6 changes: 4 additions & 2 deletions lib/ruby-fs-stack/familytree.rb
Expand Up @@ -39,15 +39,15 @@ def initialize(fs_communicator)
#
# p.version # => '90194378772'
# p.id # => 'KW3B-NNM'
def person(id_or_ids, options = {})
def person(id_or_ids, options = {}, &block)
if id_or_ids.kind_of? Array
multiple_ids = true
url = Base + 'person/' + id_or_ids.join(',')
props = properties()
if id_or_ids.size > props['person.max.ids']
persons = []
id_or_ids.each_slice(props['person.max.ids']) do |ids_slice|
persons = persons + person(ids_slice,options)
persons = persons + person(ids_slice,options,&block)
end
return persons
end
Expand All @@ -64,10 +64,12 @@ def person(id_or_ids, options = {})
response = @fs_communicator.get(url)
familytree = Org::Familysearch::Ws::Familytree::V2::Schema::FamilyTree.from_json JSON.parse(response.body)
if multiple_ids
yield(familytree.persons) if block
return familytree.persons
else
person = familytree.persons.find{|p| p.requestedId == id }
person ||= familytree.persons.first if id == 'me'
yield(person) if block
return person
end
end
Expand Down
38 changes: 38 additions & 0 deletions spec/familytree_v2/familytree_communicator_spec.rb
Expand Up @@ -74,6 +74,22 @@ def existing_person
@ft_v2_com.person(:me, :names => 'none')
end

describe "passing a block" do
it "should execute the block given" do
mock = mock('FixNum')
mock.should_receive(:call!).once.and_return(nil)
@ft_v2_com.person :me do |person|
mock.call!
end
end

it "should pass the person to the block" do
@ft_v2_com.person :me do |person|
person.id.should == 'KJ86-3VD'
end
end
end

end

describe "person read w/ multiple IDs" do
Expand Down Expand Up @@ -125,6 +141,28 @@ def existing_person
results = @com.familytree_v2.person ['KWCZ-1WL','KWCH-DGY','KWZR-RPD','KWCH-DPM','KWCH-DP9','KN1H-HBK','KLYL-KPZ','2794-46L','279W-NDV','KWJJ-5Y3','26KN-QTT','KWCV-7F7','2NQ9-FGV','K2WM-SHZ','KCR4-MBW','KWZR-RPX']
results.should have(16).things
end

describe "sending a block callback" do
before(:each) do
@ids = ['KWCZ-1WL','KWCH-DGY','KWZR-RPD','KWCH-DPM','KWCH-DP9','KN1H-HBK','KLYL-KPZ','2794-46L','279W-NDV','KWJJ-5Y3','26KN-QTT','KWCV-7F7','2NQ9-FGV','K2WM-SHZ','KCR4-MBW','KWZR-RPX']
end

it "should call the block for each slice of the persons requested" do
mock = mock('FixNum')
mock.should_receive(:call!).exactly(2).times.and_return(nil)
@com.familytree_v2.person @ids do |persons|
mock.call!
end
end

it "should pass the person or persons to the block" do
count = 0
@com.familytree_v2.person @ids do |persons|
count += persons.size
end
count.should == 16
end
end
end

describe "save_person" do
Expand Down

0 comments on commit d811d72

Please sign in to comment.