Add Metadata to Views, Presenter, and Solr - RepoCamp/ohsu2018 GitHub Wiki
Goals:
Setup
(OPTIONAL) Save your current changes
If you have changes in your current branch -- you can check on this via git status
-- you'll want to save those before starting this lesson (which uses a separate branch):
git checkout -b wip_lesson_6_start
git add .
git commit -m 'checkpoint before beginning second metadata lesson'
Check out working branch
git checkout lesson_6_start
NOTE: If you make experimental changes and want to get back to the minimal code state necessary to run this lesson, you can check the starting code out again using:
git checkout lesson_6_start
Add the field to the show view
In part one of this tutorial, we added functionality for new fields when creating a new Work. For part two, we're going focus on displaying a Work.
Add a Show feature test
- Create a new file at
spec/features/show_work_spec.rb
.
require 'rails_helper'
RSpec.feature 'Display an Work' do
let(:title) { ['Journey to Skull Island'] }
let(:creator) { ['Quest, Jane'] }
let(:keyword) { ['Pirates', 'Adventure'] }
let(:visibility) { Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_PUBLIC }
let(:user) { '[email protected]' }
let :work do
Work.create(title: title,
creator: creator,
keyword: keyword,
visibility: visibility,
depositor: user)
end
scenario "Show a public Work" do
visit("/concern/works/#{work.id}")
expect(page).to have_content work.title.first
expect(page).to have_content work.creator.first
expect(page).to have_content work.keyword.first
expect(page).to have_content work.keyword.last
end
end
- Run your test suite (
rails ci
orrspec spec
). Everything should pass.
Add the new metadata field to your show feature
- Add your new metadata field to the show spec you just created. You'll need
to add it in three places:
- As a let statement, where you define the value:
let(:year) { ['2010'] }
- In the Work.new block:
year: year
- In the expectations:
expect(page).to have_content work.year.first
- As a let statement, where you define the value:
- Run your test suite again (
rspec spec
). It should fail with the messageFailure/Error: expect(page).to have_content work.year.first
.
This tells us that our test setup ran successfully (a Work was created with a year field) but the show page doesn't display that field yet.
Modify the presenter for our Work class
Recall that Rails uses an "MVC" or "model-view-controller" pattern. In addition to models, views, and controllers, we also have presenters, sometimes also referred to as a "Decorator" or "View-Model." The presenter is responsible for translating values from the model to a presentable form.
Example:
class BookPresenter
def initialize(book)
@book = book
end
delegate :title, :creator, to: :@book
def glitter_title
'★' + @book.title + '☆'
end
end
Customize our work-specific presenter
As always, we want to write our test first.
- Hyrax generated
app/presenters/hyrax/work_presenter.rb
andspec/presenters/hyrax/work_presenter_spec.rb
for you when you created your Work work type. Open these files and take a look. - Edit
spec/presenters/hyrax/work_presenter_spec.rb
. It is only a stubbed spec right now.
require 'rails_helper'
RSpec.describe Hyrax::WorkPresenter do
subject(:presenter) { described_class.new(SolrDocument.new(work.to_solr), nil) }
let(:title) { ['Journey to Skull Island'] }
let(:creator) { ['Quest, Jane'] }
let(:keyword) { ['Pirates', 'Adventure'] }
let(:visibility) { Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_PUBLIC }
let(:user) { '[email protected]' }
let :work do
Work.new(title: title,
creator: creator,
keyword: keyword,
visibility: visibility,
depositor: user)
end
it { is_expected.to have_attributes(title: title, year: year) }
end
- Run your test suite (
rails ci
). It will fail with the messageFailure/Error: it { is_expected.to delegate_method(:year).to(:solr_document) }
- Add this line to your work_presenter.rb file:
delegate :year, to: :solr_document
Use our custom presenter
In order to use our custom presenter, our Work class has to know about it. Normally, you would have to manually add the custom presenter to the relevant controller, in this case app/controllers/hyrax/works_controller.rb
. However, Hyrax did this for you when you ran the work type generator. Open the app/controllers/hyrax/works_controller.rb
file and note that it is configured to use Hyrax::WorkPresenter.
self.show_presenter = Hyrax::WorkPresenter
OH NO! Run your test suite again,
Failure/Error: delegate :year, to: :solr_document
NoMethodError:
undefined method `year' for #<SolrDocument:0x000000000c855028>
Discussion
- Where does the presenter get its data?
- What does it mean that we "delegate" to
solr_document
? - What advantages are there to our "presenter" pattern vs. using
Work
throughout?
Check out working branch
git checkout lesson_6_mid
NOTE: If you make experimental changes and want to get back to the minimal code state necessary to run this lesson, you can check the starting code out again using:
git checkout lesson_6_mid
Add a field to view partial and solr
Add your field to the solr index
- Edit
app/models/work.rb
and add instructions for how theyear
field should be indexed:
property :year, predicate: "http://www.europeana.eu/schemas/edm/year" do |index|
index.as :stored_searchable
end
Add the field to solr_document
- Edit
app/models/solr_document.rb
and add this method:
def year
self[Solrizer.solr_name('year')]
end
Add the field to the view partial
- Copy Hyrax's
app/views/hyrax/base/_attribute_rows.html.erb
to the same directory structure in your app - Edit your newly created local copy of
_attribute_rows.html.erb
to include your metadata field:
<%= presenter.attribute_to_html(:year) %>
- Run your test suite again (
rails ci
) and your feature test should now pass
Note: You can see all the changes made during this exercise on the github repo.
Pair exercise
We added one metadata field here: year. Choose either extent or references and add a second metadata field. Or, define your own metadata field, as long as you pick something that can be a simple string.