-
Notifications
You must be signed in to change notification settings - Fork 23
Retrieving resources
- Using a query service:
- Find a resource by its ID.
- Find a resource by an alternate ID.
- Find all resources of a specific model.
- Find all members of a parent resource, and the parent of a member resource.
- Understand other relationships.
- Understand custom queries.
Reference: Valkyrie Query Documentation | Valkyrie Custom Query Documentation | postgres query_service | shared specs
Terminology
- query service - provides methods for the standard set of queries for finding resources
- custom query - additional query methods written in your app following the custom query pattern that are not part of the standard set of queries
Characteristics
- code example of postgres query_service for an example implementation of a query service
- code examples of shared specs for queries tests demonstrating expected function of query service methods
- see Valkyrie Query Documentation for the list of queries supported by all adapters
All the examples in this section assume that you completed the examples under Saving a resource. If you went beyond the examples, you may see additional results beyond those shown for each example.
To find the book by its id, you can either pass the string representation of the ID or the instance of Valkyrie::ID
.
Substitute the actual id assigned during [[Saving a resource] for AN_ID_ASSIGNED_BY_POSTGRES.
> book = ValkyriePgDemo.pg_query_service.find_by(id: '_AN_ID_ASSIGNED_BY_POSTGRES_')
> book.id
=> #<Valkyrie::ID:... @id="_AN_ID_ASSIGNED_BY_POSTGRES_">
> same_book = ValkyriePgDemo.pg_query_service.find_by(id: book.id)
> book == same_book
=> true
> book.persisted?
=> true
> book.title
=> ['Free Fall']
> book.title = "Lullaby Town"
> book.title
=> ["Lullaby Town"]
> book.persisted?
=> true # persisted? indicates only that the resource is known to exist in the database
> book == same_book
=> false # since the title was changed in book, but not same_book
NOTE: Since book
with the new title wasn't persisted again (even though the persisted?
method is returning true
), the database continues to have the original title ['Free Fall']
.
alternate_ids
is a special attribute name which the query service knows about. There are methods defined to retrieve resources by an alternate id.
The book resource was saved with alternate_ids
[#<Valkyrie::ID:0x00007fbf9c08e770 @id="b1">]
.
> book = ValkyriePgDemo.pg_query_service.find_by_alternate_identifier(alternate_identifier: 'b1')
> book.id
=> #<Valkyrie::ID:... @id="_AN_ID_ASSIGNED_BY_POSTGRES_">
> book.title
=> ["Free Fall"]
To find all books, get all resources for a model.
> books = ValkyriePgDemo.pg_query_service.find_all_of_model(model: Book)
> books.each { |b| puts("class: #{b.class} title: #{b.title}") }
=> class: Book title: ["Free Fall"]
member_ids
is a special attribute name which the query service knows about. There are methods defined to retrieve members and their parents.
If you've been playing around a bit, your objects for book and page may not have membership as expected. You can look in the database for book with members. Use find_by(id:) described above to set book. You can do something similar for page. |
> child_pages = ValkyriePgDemo.pg_query_service.find_members(resource: book)
> child_pages.each { |p| puts("class: #{p.class} page_num: #{p.page_num} structure: #{p.structure}") }
class: Page page_num: 1 structure: title page
=> nil
> parent_books = ValkyriePgDemo.pg_query_service.find_parents(resource: page)
> parent_books.each { |b| puts("class: #{b.class} title: #{b.title}") }
class: Book title: ["Free Fall"]
=> nil
There are methods to find other relationships between resources that are maintained in attributes other than member_ids. See #find_references_by and #find_inverse_references in the shared specs for details on how they work.
You can see the list of all queries that each data source adapter should support in shared_specs/queries
Reference: Custom queries in Valkyrie wiki documentation
You may want to add additional queries beyond the standard set of queries. Some reasons why you may want to implement custom queries:
- complex query that can be completed with the standard set of queries and is used in multiple places in the app
- simple or complex queries that cannot be completed with the standard set of queries. NOTE: In this case, you will need to implement these queries for each adapter your app supports.