Module: ActiveFedora::FinderMethods

Included in:
Relation
Defined in:
lib/active_fedora/relation/finder_methods.rb

Instance Method Summary collapse

Instance Method Details

#exists?(conditions) ⇒ Boolean

Returns true if object having the id or matching the conditions exists in the repository Returns false if param is false (or nil) @param[ActiveFedora::Base, String, Hash] object, id or hash of conditions @return

Returns:

  • (Boolean)


78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/active_fedora/relation/finder_methods.rb', line 78

def exists?(conditions)
  conditions = conditions.id if Base === conditions
  return false unless conditions
  case conditions
  when Hash
    search_with_conditions(conditions, rows: 1).present?
  when String
    find(conditions).present?
  else
    raise ArgumentError, "`conditions' argument must be ActiveFedora::Base, String, or Hash: #{conditions.inspect}"
  end
rescue ActiveFedora::ObjectNotFoundError, Ldp::Gone
  false
end

#find(*args) ⇒ Object

Returns an Array of objects of the Class that find is being called on

@param args either an id or a hash of conditions

Parameters:

  • args (Hash)

    a customizable set of options

Options Hash (*args):

  • :rows (Integer)

    when :all is passed, the maximum number of rows to load from solr

  • :cast (Boolean)

    when true, examine the model and cast it to the first known cModel

Raises:

  • (ArgumentError)


36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/active_fedora/relation/finder_methods.rb', line 36

def find(*args)
  return to_a.find { |*block_args| yield(*block_args) } if block_given?
  options = args.extract_options!
  options = options.dup
  cast = if @klass == ActiveFedora::Base && !options.key?(:cast)
           true
         else
           options.delete(:cast)
         end
  if options[:sort]
    # Deprecate sort sometime?
    sort = options.delete(:sort)
    options[:order] ||= sort if sort.present?
  end

  raise ArgumentError, "#{self}.find() expects an id. You provided `#{args.inspect}'" unless args.is_a? Array
  find_with_ids(args, cast)
end

#find_each(conditions = {}, opts = {}) ⇒ Object

Yields the found ActiveFedora::Base object to the passed block

Parameters:

  • conditions (Hash) (defaults to: {})

    the conditions for the solr search to match

  • opts (Hash) (defaults to: {})

Options Hash (opts):

  • :cast (Boolean) — default: true

    when true, examine the model and cast it to the first known cModel



126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/active_fedora/relation/finder_methods.rb', line 126

def find_each(conditions = {}, opts = {})
  cast = opts.delete(:cast)
  search_in_batches(conditions, opts.merge(fl: ActiveFedora.id_field)) do |group|
    group.each do |hit|
      begin
        yield(load_from_fedora(hit[ActiveFedora.id_field], cast))
      rescue Ldp::Gone
        ActiveFedora::Base.logger.error "Although #{hit[ActiveFedora.id_field]} was found in Solr, it doesn't seem to exist in Fedora. The index is out of synch." if ActiveFedora::Base.logger
      end
    end
  end
end

#find_one(id, cast = nil) ⇒ Object

Retrieve the Fedora object with the given id, explore the returned object Raises a ObjectNotFoundError if the object is not found.

Examples:

because the object hydra:dataset1 asserts it is a Dataset (hasModel fedora.info/definitions/v4/model#Dataset), return a Dataset object (not a Book).

Book.find_one("hydra:dataset1")

Parameters:

  • id (String)

    of the object to load

  • cast (Boolean) (defaults to: nil)

    when true, cast the found object to the class of the first known model defined in it’s RELS-EXT



179
180
181
182
183
184
185
186
187
# File 'lib/active_fedora/relation/finder_methods.rb', line 179

def find_one(id, cast = nil)
  if where_values.empty?
    load_from_fedora(id, cast)
  else
    conditions = where_values + [ActiveFedora::SolrQueryBuilder.construct_query(ActiveFedora.id_field => id)]
    query = conditions.join(" AND ".freeze)
    to_enum(:find_each, query, {}).to_a.first
  end
end

#find_takeObject



66
67
68
69
70
71
72
# File 'lib/active_fedora/relation/finder_methods.rb', line 66

def find_take
  if loaded?
    @records.first
  else
    @take ||= limit(1).to_a.first
  end
end

#firstObject

Returns the first records that was found.

Examples:

Person.where(name_t: 'Jones').first
  => #<Person @id="foo:123" @name='Jones' ... >


8
9
10
11
12
13
14
# File 'lib/active_fedora/relation/finder_methods.rb', line 8

def first
  if loaded?
    @records.first
  else
    @first ||= limit(1).to_a[0]
  end
end

#lastObject

Returns the last record sorted by id. ID was chosen because this mimics how ActiveRecord would achieve the same behavior.

Examples:

Person.where(name_t: 'Jones').last
  => #<Person @id="foo:123" @name='Jones' ... >


22
23
24
25
26
27
28
# File 'lib/active_fedora/relation/finder_methods.rb', line 22

def last
  if loaded?
    @records.last
  else
    @last ||= order('id desc').limit(1).to_a[0]
  end
end

#search_by_id(id, opts = {}) ⇒ Object

Returns a single solr hit matching the given id

Parameters:

  • id (String)

    document id

  • opts (Hash) (defaults to: {})


110
111
112
113
114
115
116
117
118
119
# File 'lib/active_fedora/relation/finder_methods.rb', line 110

def search_by_id(id, opts = {})
  opts[:rows] = 1
  result = search_with_conditions({ id: id }, opts)

  if result.empty?
    raise ActiveFedora::ObjectNotFoundError, "Object #{id} not found in solr"
  end

  result.first
end

#search_in_batches(conditions, opts = {}) ⇒ Object

Yields each batch of solr records that was found by the find options as an array. The size of each batch is set by the :batch_size option; the default is 1000.

Returns a solr result matching the supplied conditions @param conditions solr conditions to match @param options

Examples:

Person.search_in_batches('age_t'=>'21', {:batch_size=>50}) do |group|
group.each { |person| puts person['name_t'] }
end

Parameters:

  • opts (Hash) (defaults to: {})

    a customizable set of options

Options Hash (opts):

  • :sort (Array)

    a list of fields to sort by

  • :rows (Array)

    number of rows to return



153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/active_fedora/relation/finder_methods.rb', line 153

def search_in_batches(conditions, opts = {})
  opts[:q] = create_query(conditions)
  opts[:qt] = @klass.solr_query_handler
  # set default sort to created date ascending
  opts[:sort] = @klass.default_sort_params unless opts[:sort].present?

  batch_size = opts.delete(:batch_size) || 1000
  select_path = ActiveFedora::SolrService.select_path

  counter = 0
  loop do
    counter += 1
    response = ActiveFedora::SolrService.instance.conn.paginate counter, batch_size, select_path, params: opts
    docs = response["response"]["docs"]
    yield docs
    break unless docs.has_next?
  end
end

#search_with_conditions(conditions, opts = {}) ⇒ Object

Returns a solr result matching the supplied conditions @param conditions can either be specified as a string, or hash representing the query part of an solr statement. If a hash is provided, this method will generate conditions based simple equality combined using the boolean AND operator.

Parameters:

  • options (Hash)
  • opts (Hash) (defaults to: {})

    a customizable set of options

Options Hash (opts):

  • :sort (Array)

    a list of fields to sort by

  • :rows (Array)

    number of rows to return



101
102
103
104
105
# File 'lib/active_fedora/relation/finder_methods.rb', line 101

def search_with_conditions(conditions, opts = {})
  # set default sort to created date ascending
  opts[:sort] = @klass.default_sort_params unless opts.include?(:sort)
  SolrService.query(create_query(conditions), opts)
end

#take(limit = nil) ⇒ Object

Gives a record (or N records if a parameter is supplied) without any implied order. The order will depend on the database implementation. If an order is supplied it will be respected.

Person.take # returns an object fetched by SELECT * FROM people LIMIT 1
Person.take(5) # returns 5 objects fetched by SELECT * FROM people LIMIT 5
Person.where(["name LIKE '%?'", name]).take


62
63
64
# File 'lib/active_fedora/relation/finder_methods.rb', line 62

def take(limit = nil)
  limit ? limit(limit).to_a : find_take
end