Oai pmh events - #1352
Conversation
There was a problem hiding this comment.
Pull request overview
This PR extends the OAI-PMH endpoint to expose Event records alongside Material records, including Dublin Core and RDF serializations and set filtering to allow clients to harvest only events or only materials.
Changes:
- Add
Event#to_oai_dcandEvent#to_rdfserialization methods and corresponding model tests. - Replace the single-model OAI provider wrapper with a new
MultiModelprovider model to merge Materials + Events and expose OAI sets. - Expand OAI controller integration tests to cover event records, sets, and resumption token paging behavior.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| test/models/event_test.rb | Adds unit tests validating Event OAI-DC + RDF serialization. |
| test/controllers/oai_controller_test.rb | Adds integration tests for events in OAI responses, ListSets, and paging/resumption tokens. |
| config/initializers/oai_provider.rb | Introduces MultiModel to merge multiple AR scopes into one OAI-PMH model and expose sets. |
| app/models/event.rb | Implements to_oai_dc and to_rdf serialization for events. |
| app/controllers/oai_controller.rb | Switches OAI endpoint to use MultiModel over both visible Materials and Events. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…sources with same date in oai-pmh endpoint Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
… of OAI-PMH results
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.
Suppressed comments (1)
test/controllers/oai_controller_test.rb:146
- The pagination setup counts all visible Events/Materials across every space, but the OAI endpoint only serves
in_current_space. If fixtures include visible records in non-current spaces,base_countwill be too high,records_neededtoo low, and this test can fail to generate enough records to trigger a resumption token.
base_count = Event.where(visible: true).count + Material.where(visible: true).count
records_needed = [0, 105 - base_count].max
fbacall
left a comment
There was a problem hiding this comment.
One comment, plus a potential performance improvement...
When I tried this locally and visited the /oai-pmh endpoint to list records, it performed ~500 queries and took ~600ms to respond.
I added this after line 43 of the OAI provider:
scopes = scopes.map do |s|
fields = [:contributors, :operation_links, :scientific_topic_links, :content_provider]
fields << :instructors if s.model == Event
fields << :materials if s.model == Event
fields << :authors if s.model == Material
s.includes(*fields)
endto eager load various associations that are used in the to_oai_dc methods, which cut it down to 19 queries and ~122ms.
Potentially worth investigating (and finding a less hacky way of doing) this. Maybe the OAI library allows you to eager load associations like sunspot does
| def sets | ||
| model_scopes.map do |scope| | ||
| n = scope.model.model_name | ||
| OAI::Set.new({ spec: n.route_key, name: n.plural.titleize, description: "Set of all training #{n.plural.humanize.downcase}" }) |
There was a problem hiding this comment.
Can we get the description from i18n somehow instead of hard-coding it here?
Summary of changes
Motivation and context
Closes #1351
Screenshots
Events can be found alongside materials in the OAI-PMH results:

Checklist