class Yt::Relation
Provides methods to iterate through collections of YouTube resources. @private
Public Class Methods
@param [Class] item_class the class of objects to initialize when
iterating through a collection of YouTube resources.
@yield [Hash] the options to change which items to iterate through.
# File lib/yt/relation.rb, line 10 def initialize(item_class, options = {}, &item_block) @options = {parts: %i(id), limit: Float::INFINITY, item_class: item_class, initial_items: -> {[]}, extract_items: -> (body) {body['items']}} @options.merge! options @item_block = item_block end
Public Instance Methods
# File lib/yt/relation.rb, line 47 def attributes_for_new_item(item) {}.tap do |matching_parts| item.each_key do |key| part = key.gsub(/([A-Z])/) { "_#{$1.downcase}" }.to_sym if @options[:parts].include? part matching_parts[part] = item[key] end end end end
Let's start without memoizing
# File lib/yt/relation.rb, line 18 def each @last_index = 0 while next_item = find_next break if @last_index > @options[:limit] yield next_item end end
# File lib/yt/relation.rb, line 26 def find_next @items ||= initial_items.dup if @items[@last_index].nil? && more_pages? response = Response.new(@options, &@item_block).run more_items = @options[:extract_items].call(response.body).map do |item| @options[:item_class].new attributes_for_new_item(item) end @options.merge! offset: response.body['nextPageToken'] if response.body @items.concat more_items end @items[(@last_index +=1) -1] end
# File lib/yt/relation.rb, line 43 def initial_items @initial_items ||= @options[:initial_items].call end
@return [String] a representation of the Yt::Relation
instance.
# File lib/yt/relation.rb, line 96 def inspect entries = take(3).map!(&:inspect) if entries.size == 3 entries[2] = '...' end "#<#{self.class.name} [#{entries.join(', ')}]>" end
Specifies how many items to fetch when hitting the data API. @param [Integer] max_results The maximum number of items to fetch. @return [Yt::Relation] itself.
# File lib/yt/relation.rb, line 90 def limit(max_results) @options.merge! limit: max_results self end
# File lib/yt/relation.rb, line 39 def more_pages? (@last_index == initial_items.size) || !@options[:offset].nil? end
Specifies which parts of the resource to fetch when hitting the data API. @param [Array<Symbol>] parts The parts to fetch. @return [Yt::Relation] itself.
# File lib/yt/relation.rb, line 68 def select(*parts) if @options[:parts] != parts + %i(id) @items = nil @options.merge! parts: (parts + %i(id)) end self end
@return [Integer] the estimated number of items in the collection.
# File lib/yt/relation.rb, line 59 def size size_options = @options.merge parts: %i(id), limit: 1 @response = Response.new(size_options, &@item_block).run [@response.body['pageInfo']['totalResults'], @options[:limit]].min end
Specifies which items to fetch when hitting the data API. @param [Hash<Symbol, String>] conditions The conditions for the items. @return [Yt::Relation] itself.
# File lib/yt/relation.rb, line 79 def where(conditions = {}) if @options[:conditions] != conditions @items = [] @options.merge! conditions: conditions end self end