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 false if param is false (or nil)

Parameters:

Returns:

  • (Boolean)

    true if object having the id or matching the conditions exists in the repository



73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/active_fedora/relation/finder_methods.rb', line 73

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, ActiveFedora::ModelMismatch, Ldp::Gone
  false
end

#find(*args) ⇒ Array

Returns objects of the Class that find is being called on.

Parameters:

  • args (String, Hash)

    either an id or a hash of conditions

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

Returns:

  • (Array)

    objects of the Class that find is being called on

Raises:

  • (ArgumentError)


32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/active_fedora/relation/finder_methods.rb', line 32

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



117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/active_fedora/relation/finder_methods.rb', line 117

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::ObjectNotFoundError
        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."
      end
    end
  end
end

#find_one(id, cast = nil) ⇒ Object

Retrieve the Fedora object with the given id

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

Raises:



169
170
171
172
173
174
175
176
177
# File 'lib/active_fedora/relation/finder_methods.rb', line 169

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



62
63
64
65
66
67
68
# File 'lib/active_fedora/relation/finder_methods.rb', line 62

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

#firstObject

Returns the first record that was found.

Examples:

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


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

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' ... >


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

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: {})


103
104
105
106
107
108
109
110
# File 'lib/active_fedora/relation/finder_methods.rb', line 103

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

Examples:

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

Parameters:

  • conditions (Hash)

    solr conditions to match

  • 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



144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/active_fedora/relation/finder_methods.rb', line 144

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 If a hash is provided, query will combine based on simple equality using the boolean AND operator.

Parameters:

  • conditions (Hash, String)

    represention of the query part of an solr statement.

  • 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



94
95
96
97
98
# File 'lib/active_fedora/relation/finder_methods.rb', line 94

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


58
59
60
# File 'lib/active_fedora/relation/finder_methods.rb', line 58

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