hydra 6.2.0.rc1 → 6.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -1
  3. data/CONTRIBUTING.md +3 -0
  4. data/RELEASE-POLICY.md +40 -0
  5. data/doc/Configuring-solr-and-fedora.md +16 -0
  6. data/doc/Content-Type-Example:-Journal-Article.textile +735 -0
  7. data/doc/Dive-into-Hydra.md +62 -0
  8. data/doc/Filtering-search-results-with-hydra-access-controls.md +16 -0
  9. data/doc/For-Developers.md +47 -0
  10. data/doc/Home.md +33 -0
  11. data/doc/Lesson:-Define-Relationships-Between-Objects.md +127 -0
  12. data/doc/Lesson:-Generate-Rails-Scaffolding-for-Creating-and-Editing-Books.md +167 -0
  13. data/doc/Lesson:-Reading-Hydra-rightsMetadata-XML.md +87 -0
  14. data/doc/Lesson:-Use-Hydra-Access-Controls-to-Control-Access-to-Blacklight-show-Pages.md +37 -0
  15. data/doc/Lesson:-Using-Hydra-Access-Controls-and-CanCan-to-conditionally-render-part-of-a-page.md +29 -0
  16. data/doc/Lesson:-add-the-Hydra-dependencies.md +28 -0
  17. data/doc/Lesson:-adding-content-datastreams.md +60 -0
  18. data/doc/Lesson:-build-a-book-model.md +262 -0
  19. data/doc/Lesson:-create-a-git-repository.md +35 -0
  20. data/doc/Lesson:-generate-a-rails-application.md +53 -0
  21. data/doc/Lesson:-install-hydra-jetty.md +57 -0
  22. data/doc/Lesson:-make-blacklight-return-search-results.md +47 -0
  23. data/doc/Lesson:-run-the-Hydra-generator.md +39 -0
  24. data/doc/Lesson:-set-up-your-Rails-Application-to-use-rspec.md +41 -0
  25. data/doc/Lesson:-start-jetty.md +85 -0
  26. data/doc/Lesson:-start-the-application-&-search-for-results.md +43 -0
  27. data/doc/Lesson:-turn-off-access-controls.md +37 -0
  28. data/doc/Migrating-to-Hydra-6.2.md +12 -0
  29. data/doc/Migration-Notes.md +2 -0
  30. data/doc/Models---Defining-a-Custom-Hydra-Model.textile +198 -0
  31. data/doc/Rake-Tasks-in-Hydra-Head.textile +40 -0
  32. data/doc/Reference.textile +19 -0
  33. data/doc/Solr-Schema.rdoc +44 -0
  34. data/doc/Tools-for-Developing-and-Testing-your-Application.textile +69 -0
  35. data/doc/YOUR-Hydra-Application---Initial-Modifications.textile +357 -0
  36. data/lib/hydra/version.rb +1 -1
  37. metadata +35 -4
@@ -0,0 +1,62 @@
1
+ This tutorial is known to work with [hydra](http://rubygems.org/gems/hydra) release version 6.1.0.
2
+ _Please update this wiki to reflect any other versions that have been tested._
3
+
4
+ # Prerequisites
5
+
6
+ This tutorial assumes that you have some basic familiarity with Ruby and Rails. If you are new to Rails, we recommend going through the [RailsBridge Tutorial](http://curriculum.railsbridge.org/intro-to-rails/) first.
7
+
8
+ A fun way to learn about the basic Rails syntax and patterns is the [Rails for Zombies](http://railsforzombies.org/) tutorial.
9
+
10
+ The tutorial also mentions using [Ruby Version Manager](http://rvm.io), a.k.a RVM. Before starting this tutorial, visit the [RVM website](http://rvm.io/) to learn about how that tool is used. RVM is not required in order to do the tutorial, but you will probably find it useful.
11
+
12
+ # System Requirements
13
+ Your system should have the following installed before beginning the walkthrough
14
+ + [ruby](http://www.ruby-lang.org/en/) 1.9.3 or 2.0.0
15
+ + [rails](http://rubyonrails.org/) ~>3.2.13 or ~>4.0.0
16
+ + [git](http://git-scm.com/)
17
+ + [java](http://www.java.com/en/) runtime >= 6.0
18
+
19
+ # Goals
20
+ * Create a Hydra Head
21
+ * Run Fedora and Solr underneath the Hydra Head
22
+ * Start & Stop the Application
23
+ * Start & Stop Fedora and Solr
24
+ * Define Models for Content to put into your Hydra Head (in this case Books and Pages)
25
+ * Use your Models to Create objects in Fedora and Solr
26
+ * See where content is persisted in Fedora and indexed in Solr
27
+ * Modify how metadata is indexed in Solr
28
+ * Use Git to Track Code Changes
29
+
30
+ # Steps/Lessons
31
+ 1. [[Lesson: Generate a Rails Application]]
32
+ 1. [[Lesson: Create a git Repository]]
33
+ 1. [[Lesson: Add the Hydra Dependencies]]
34
+ 1. [[Lesson: Run the Hydra generator]]
35
+ 1. [[Lesson: Install hydra-jetty]]
36
+ 1. [[Lesson: Start Jetty]]
37
+ 1. [[Lesson: Start the Application & Search for Results]]
38
+ 1. [[Lesson: Build a Book Model]]
39
+ 1. [[Lesson: Turn Off Access Controls]]
40
+ 1. [[Lesson: Make Blacklight Return Search Results]]
41
+
42
+ ## Bonus
43
+ You've completed the main tutorial, the following lessons can be completed in any order based on your interests:
44
+
45
+ 1. [[Lesson: Define Relationships Between Objects]]
46
+ 1. [[Lesson: Adding Content Datastreams]]
47
+ 1. [[Lesson: Generate Rails Scaffolding for Creating and Editing Books]]
48
+ 1. [[Lesson: Set up your Rails Application to use RSpec]]
49
+
50
+ # Next Steps
51
+ You've finished the initial Hydra tutorial and learned about setting up the basic hydra framework, building basic data models, establishing relationships between models, and modifying the basic user interface provided in a default hydra install. There is still lots more to learn. At this point, you can explore the ideas in this tutorial further by spending some time building out your models to support more complex metadata, further customizing your application views, and/or adding tests to make your applications more robust and easy to maintain.
52
+
53
+ There's lots more Hydra though, so you may wan to check out the following tutorials
54
+ - [Tame Your XML With OM](https://github.com/projecthydra/om/wiki/Tame-your-XML-with-OM) shows you how to configure Hydra to parse metadata from source XML documents
55
+ - [Access Controls with Hydra](https://github.com/projecthydra/hydra-head/wiki/Access-Controls-with-Hydra) teaches you to configure roles and access rights that determine which content can be viewed by various user roles assigned to users of your repository
56
+ - Even though the information there is not specific to Hydra, [Getting Started with Rails](http://guides.rubyonrails.org/getting_started.html) is a great place to learn more about Model, View, and Controller conventions within Rails that can be applied to building your own Hydra-based repository.
57
+
58
+ You should also say hello on the [hydra-tech mailing list](https://groups.google.com/forum/?fromgroups#!forum/hydra-tech) and let us know what you're using Hydra for.
59
+
60
+ Check out the Hydra Project Website at [http://projecthydra.org](http://projecthydra.org)
61
+
62
+ ![Project Hydra Logo](https://github.com/uvalib/libra-oa/blob/a6564a9e5c13b7873dc883367f5e307bf715d6cf/public/images/powered_by_hydra.png?raw=true)
@@ -0,0 +1,16 @@
1
+ In you catalog_controller.rb add the following lines:
2
+
3
+ ```
4
+ include Hydra::Controller::ControllerBehavior
5
+ before_filter :enforce_show_permissions, :only=>:show
6
+ CatalogController.solr_search_params_logic += [:add_access_controls_to_solr_params]
7
+ ```
8
+
9
+ Additionally, if you want to remove FileAssets from search results you can add:
10
+ ```
11
+ CatalogController.solr_search_params_logic += [:exclude_unwanted_models]
12
+ ```
13
+
14
+ Running the generator: `rails g hydra:head` typically takes care of this for you.
15
+
16
+
@@ -0,0 +1,47 @@
1
+ ## Community Principles
2
+ Hydra Community Principles
3
+
4
+ ## Getting Connected
5
+ Mailing lists, committers calls, etc. are all listed on the [Connect](https://wiki.duraspace.org/display/hydra/Connect) page of the [The Hydra Project wiki](https://wiki.duraspace.org/display/hydra/The+Hydra+Project).
6
+
7
+ ## Getting Code
8
+ All of our code is hosted on Github in the [projecthydra](https://github.com/projecthydra) account.
9
+
10
+ ## On-line Resources and Tutorials
11
+ ### For New and Potential Adopters:
12
+ * New adopters and potential adopters may find the pages here useful: http://projecthydra.org/
13
+ * See Hydra Heads (Known Implementations) for more information about each of the Hydra Heads.
14
+ * Developers may find the [Hydra-Head Walkthrough](https://github.com/projecthydra/hydra-head/wiki/Code4lib-walkthrough) useful.
15
+
16
+ ### For Architecture Level:
17
+ * See the Duraspace projecthydra wikis for information at the architecture level: http://wiki.duraspace.org/display/hydra/
18
+
19
+ ### For Developers:
20
+ * Code is hosted on Github: https://github.com/projecthydra
21
+ * Each of the gems in the hydra framework has its own wiki associated its individual code repository
22
+ * [Contributing code](https://github.com/projecthydra/hydra/blob/master/CONTRIBUTING.md)
23
+ * API documentation (class and method level documentation) is currently published for each build on the Hydra Continuous Integration Server.
24
+ * Some particular documents of interest (these may migrate to the github wikis for these github repositories)
25
+ * A Hydra Head interactive tutoral lives [here](https://github.com/projecthydra/hydra-head/wiki/Code4lib-walkthrough)
26
+ * [How to Get Started building your Hydra Head](https://github.com/projecthydra/hydra-head/wiki/How-to-Get-Started)
27
+ * [Steps to Defining a new Model for your Hydra Applications](https://wiki.duraspace.org/display/hydra/Steps+to+Defining+a+new+Model+for+your+Hydra+Applications)
28
+ * [ActiveFedora Console Tour] (https://github.com/projecthydra/active_fedora/wiki/Getting-Started:-Console-Tour)
29
+ * [OM documentation](https://github.com/projecthydra/om/blob/master/README.textile)
30
+ * Recommended Code Commenting Practices: think about using [YARD](http://rubydoc.info/docs/yard/file/docs/GettingStarted.md), at least provide comments that can illuminate [RDoc](http://rdoc.rubyforge.org) generated documentation
31
+ * Hydra's Bundled Jetty https://github.com/projecthydra/hydra-jetty
32
+ * [OM Terminologies in the Wild](https://wiki.duraspace.org/display/hydra/OM+Terminologies+in+the+Wild)
33
+
34
+ ## What Developer Skills are Needed?
35
+ The curriculum for Data Curation Experts's annual HydraCamp reflects the skills that a Hydra development team should ideally have. They should be able to:
36
+ * build a Rails3 Application with RSpec & Capybara tests and track it in Git
37
+ * work with MVC, Rails Plugins, Git workflow, and be able to write good tickets
38
+ * model & create Fedora objects with XML & RDF metadata then index them in Solr
39
+ * use Blacklight to build a customized Solr-driven search/discovery interface
40
+ * build a user interface for creating and editing Fedora objects
41
+ ## Where Can Developers Get Training?
42
+ The community offers multi-day public HydraCamps at least once a year in North America. Additional single and half-day workshops are frequently offered in conjunction with other major Library and Library Technology Conferences. HydraCamps are typically facilitated by Data Curation Experts who can also be engaged for private HydraCamp events or custom training engagements. Contact Information is available at http://curationexperts.com
43
+
44
+ ## Tickets: Reporting Bugs & Requesting Features
45
+ We use Github, issues as our project tracker. Please report issues against the git repository for the specific gem you are having issues with. If you are unable to identify the gem in which your problem is occurring, please e-mail the hydra-tech@googlegroups.com mailing list to help narrow your issue.
46
+
47
+ For examples, see the issues here: https://github.com/projecthydra/hydra-head/issues
@@ -0,0 +1,33 @@
1
+ # Hydra Developer Wiki
2
+
3
+ The projecthydra gem is a container gem which locks major version dependencies for a complete release of the hydra framework. Requiring this gem or including it in your Gemfile will load or install a coherent set of hydra gems developed and tested for interoperability. Developers requiring the most current functionality may choose to omit this gem and build their gem dependencies manually.
4
+
5
+ This wiki is targeted towards developers who are implementing Hydra Heads. The [Duraspace wiki](http://wiki.duraspace.org/display/hydra/) has information discussing the Hydra architecture. There's also information for new and potential adopters on the [project web site](http://projecthydra.org).
6
+
7
+ ## Getting Started
8
+
9
+ - **Tutorial:** [[Dive into Hydra]]
10
+ - **Tutorial:** [Tame Your XML With OM](https://github.com/projecthydra/om/wiki/Tame-your-XML-with-OM)
11
+ - **Tutorial:** [Access Controls with Hydra](https://github.com/projecthydra/hydra-head/wiki/Access-Controls-with-Hydra)
12
+
13
+
14
+ ## Documentation
15
+
16
+ - [Developer documentation](https://github.com/projecthydra/hydra/wiki/For-Developers)
17
+ - [Technical Framework and its Parts](https://wiki.duraspace.org/display/hydra/Technical+Framework+and+its+Parts)
18
+ - [API Documentation](http://rdoc.info/github/projecthydra/hydra-head/)
19
+ - [[Rake Tasks in Hydra Head]]
20
+ - [Understanding Hydra Access Controls](https://github.com/projecthydra/hydra-head/wiki/Access-Controls)
21
+ - [Filtering Search Results With Hydra Access Controls](https://github.com/projecthydra/hydra-head/wiki/Filtering-search-results-with-hydra-access-controls)
22
+ - [File Uploads](https://github.com/projecthydra/hydra-head/wiki/File-uploads)
23
+ - [File Downloads](https://github.com/projecthydra/hydra-head/wiki/File-downloads)
24
+ - [[Configuring Solr and Fedora]]
25
+ - [Deployment Hardware](https://wiki.duraspace.org/display/hydra/Deployment+Hardware+Information)
26
+ - [[Migration Notes]]
27
+
28
+
29
+ ### Reference for Hydra Contributors/Committers
30
+
31
+ If you are making changes to the hydra-head code itself, you will want to read
32
+
33
+ - [How to Contribute](https://github.com/projecthydra/hydra/blob/master/CONTRIBUTING.md)
@@ -0,0 +1,127 @@
1
+ This lesson is known to work with hydra version 6.1.0.
2
+ _Please update this wiki to reflect any other versions that have been tested._
3
+
4
+ # Goals
5
+ * Set up Models to represent relationships between different types of objects
6
+ * Create and modify relationships between objects
7
+
8
+ # Explanation
9
+ Now that we have created a model for Books, we will create a separate model for Pages and set a relationship between the two models indicating that any Book can have many Pages and Pages know what Book they belong to.
10
+
11
+ The syntax for declaring relationships between ActiveFedora models is the same syntax used by ActiveRecord. It's called the ActiveModel syntax. Underneath the hood, the two libraries implement relationships in very different ways. ActiveRecord uses relational database techniques like foreign keys and join tables while ActiveFedora puts this information into RDF relationships in the RELS-EXT datastreams of your Fedora objects. In both cases you can use the ActiveRecord methods to handle relationships.
12
+
13
+ # Steps
14
+
15
+ ### Step 1: Create an OM Terminology for Page metadata
16
+
17
+ Next we're going to add a Page model. We'll start by creating another simple metadata datastream. This time open ```app/models/datastreams/page_metadata.rb``` and add this content:
18
+ ```ruby
19
+ class PageMetadata < ActiveFedora::OmDatastream
20
+
21
+ set_terminology do |t|
22
+ t.root(path: "fields")
23
+ t.number index_as: :stored_searchable, type: :integer
24
+ t.text index_as: :stored_searchable
25
+
26
+ end
27
+
28
+ def self.xml_template
29
+ Nokogiri::XML.parse("<fields/>")
30
+ end
31
+ end
32
+
33
+ ```
34
+
35
+ ### Step 2: Create a Page model and make Pages aware of which Book they belong to
36
+
37
+ Then we'll build a Page model that uses the datastream. Open ```app/models/page.rb``` and paste this in:
38
+
39
+ ```ruby
40
+ class Page < ActiveFedora::Base
41
+ has_metadata 'descMetadata', type: PageMetadata
42
+
43
+ belongs_to :book, :property=> :is_part_of
44
+
45
+ has_attributes :number, datastream: 'descMetadata', multiple: false
46
+ has_attributes :text, datastream: 'descMetadata', multiple: false
47
+
48
+ end
49
+ ```
50
+
51
+ This is very similar to how our Book class looks, with the exception of the line ```belongs_to :book```. This establishes a relationship between the book and page model nearly the same as you would do with ActiveRecord. In ActiveFedora, we have to add the :property attribute as well. Relationships are stored as RDF within the RELS-EXT datastream. The :property is actually an RDF predicate.
52
+
53
+ ### Step 3: Make Books aware of their Pages
54
+
55
+ Let's edit the Book class and add the other half of the relationship:
56
+
57
+ ```ruby
58
+ # within app/models/book.rb
59
+ has_many :pages, :property=> :is_part_of
60
+ ```
61
+
62
+ ### Step 4: In the Console, manipulate relationships between Book and Page objects
63
+
64
+ Save your changes and then reopen the rails console. Now we ought to be able to create some associations.
65
+
66
+ ```ruby
67
+ b = Book.find("changeme:1")
68
+ => #<Book pid:"changeme:1", title:"Anna Karenina", author:"Tolstoy, Leo">
69
+ p = Page.new(number: 1, text: "Happy families are all alike; every unhappy family is unhappy in its own way.")
70
+ => #<Page pid:"", number:1, text:"Happy families are all alike; every unhappy family is unhappy in its own way.">
71
+ p.book = b
72
+ => #<Book pid:"changeme:1", title:"Anna Karenina", author:"Tolstoy, Leo">
73
+ p.save
74
+ => true
75
+ b.pages
76
+ => [#<Page pid:"changeme:2", number:1, text:"Happy families are all alike; every unhappy family is unhappy in its own way.">]
77
+ ```
78
+
79
+ ### Step 5: Look at the RDF (if you want to)
80
+
81
+ **Note:** If you don't know what RDF is and don't care to know, you can skip this step.
82
+
83
+ Let's look at the RDF that active-fedora uses to represent these relationships. This metadata is written into the RELS-EXT datastream of your objects. To see that content, either output it on the command line like this:
84
+
85
+ ```ruby
86
+ puts p.datastreams["RELS-EXT"].to_rels_ext
87
+ ```
88
+ Alternatively, look at the datastream in your browser at [http://localhost:8983/fedora/objects/changeme:2/datastreams/RELS-EXT/content](http://localhost:8983/fedora/objects/changeme:2/datastreams/RELS-EXT/content) (You might need to change the pid in the URL if your page's pid isn't changeme:2)
89
+
90
+ Either way, you should see RDF that looks like this:
91
+
92
+ ```
93
+ <?xml version="1.0" encoding="UTF-8"?>
94
+ <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:ns0="info:fedora/fedora-system:def/model#" xmlns:ns1="info:fedora/fedora-system:def/relations-external#">
95
+ <rdf:Description rdf:about="info:fedora/changeme:2">
96
+ <ns0:hasModel rdf:resource="info:fedora/afmodel:Page"/>
97
+ <ns1:isPartOf rdf:resource="info:fedora/changeme:1"/>
98
+ </rdf:Description>
99
+ </rdf:RDF>
100
+ ```
101
+
102
+ As you can see, it is creating rdf assertions of `info:fedora/fedora-system:def/relations-external#isPartOf` `info:fedora/changeme:1` and `info:fedora/fedora-system:def/model#hasModel` `info:fedora/afmodel:Page`.
103
+
104
+ The model assertion is created automatically based on the name of your ActiveFedora model (in this case, Page), but how did ActiveFedora know to use the predicate `info:fedora/fedora-system:def/relations-external#isPartOf` when your `belongs_to` specified a property called :is_part_of?
105
+
106
+ In other words, how did we get from
107
+
108
+ ```ruby
109
+ belongs_to :book, :property=> :is_part_of
110
+ ```
111
+
112
+ to ``info:fedora/fedora-system:def/relations-external#isPartOf`?
113
+
114
+ The answer is that active-fedora has a config file that it uses to look up RDF predicates based on the property name you specify in your model. By default, these predicates are read from the active-fedora gem, but you can override them by creating your own copy in config/predicate_mappings.yml in your own application. To see the default mappings, look at active-fedora's default [predicate mappings YAML file] (https://github.com/projecthydra/active_fedora/blob/master/config/predicate_mappings.yml) on github.
115
+
116
+ ### Step 6: Commit your changes
117
+
118
+ Now that we've added page relationships, it's a great time to commit to git:
119
+
120
+ ```bash
121
+ $> git add .
122
+ $> git commit -m "Created a book page model with relationship to the book model"
123
+ ```
124
+
125
+ # Next Step
126
+ Go on to [[Lesson: Adding Content Datastreams]] or
127
+ explore other [Dive into Hydra](Dive into Hydra#Bonus) tutorial bonus lessons.
@@ -0,0 +1,167 @@
1
+ This Tutorial is known to work with hydra version 6.1.0.
2
+ _Please update this wiki to reflect any other versions that have been tested._
3
+
4
+ # Goals
5
+
6
+ - Understand the difference between unique (single-value) and multi-valued metadata fields
7
+ - Learn how to make modifications to the views which support CRUD (Create, Read, Update, Delete) on objects in your repo
8
+
9
+ # Explanation
10
+
11
+ This lesson walks you through modifying the "Title" field in your book model to make it either single- or multi-valued. The lesson then walks through the changes necessary to modify views to read, create, and edit your updated metadata model.
12
+
13
+ # Steps
14
+
15
+
16
+ ### Step 1: Set up Rails Scaffolding for creating and editing Books
17
+
18
+ We will use the Rails scaffold generator to set up the routes, Controller and Views we need in order to CRUD books.
19
+
20
+ **Note:** If you are not familiar with the ideas of Controllers, Views and routes, or aren't familiar with the Rails scaffold generator, go through the [Railsbridge Curriculum](http://curriculum.railsbridge.org/curriculum/curriculum) and then come back to this lesson. You might also want to read the [Getting Started with Rails](http://guides.rubyonrails.org/getting_started.html) guide.
21
+
22
+ Tell the generator to build scaffolding for the Book model and make it assume books have `title` and `author` attributes like the ones we set up earlier in [[Lesson: build a book model]].
23
+ ```text
24
+ rails generate scaffold Book title:string author:string
25
+ ```
26
+
27
+ When it asks you whether to overwrite `app/models/book.rb`, enter `n` and hit enter.
28
+
29
+ Depending on the specific version of rails you are running the generator creates a few things that we don't want in the `test` and `db` directories. Delete them with the `git clean` command.
30
+
31
+ ```bash
32
+ $ git clean -df test db
33
+ ```
34
+ You'll see output something like this:
35
+ ```text
36
+ Removing db/migrate/20130417230046_create_books.rb
37
+ Removing test/fixtures/books.yml
38
+ Removing test/functional/books_controller_test.rb
39
+ Removing test/unit/book_test.rb
40
+ Removing test/unit/helpers/
41
+ ```
42
+
43
+ ### Step 2: Commit your work
44
+
45
+ ```text
46
+ git add .
47
+ git commit -m "Ran scaffold generator"
48
+ ```
49
+
50
+ ### Step 3: Run the server & Explore
51
+
52
+ Run the `rails server` and visit [[http://localhost:3000/books]]
53
+
54
+ Explore the pages for creating, editing and showing Books.
55
+
56
+ ### Step 4: Make the Display view show Authors as a multi-valued field
57
+
58
+ Open `app/models/book.rb` and edit the unique setting to be 'false':
59
+
60
+ ```ruby
61
+ has_attributes :author, datastream: 'descMetadata', multiple: true
62
+ ```
63
+
64
+ Now you need to tell your hydra application how to display multivalued fields in the 'show' (Display) view for this model.
65
+ In `app/views/books/show.html.erb` find the lines that display the author field.
66
+ ```erb
67
+ <p>
68
+ <b>Author:</b>
69
+ <%= @book.author %>
70
+ </p>
71
+ ```
72
+
73
+ We want to make these lines iterate over the values returned by `@book.author` and put them in a list
74
+ ```erb
75
+ <p>
76
+ <b>Author(s):</b>
77
+ <ul>
78
+ <%- @book.author.each do |author|%>
79
+ <li><%= author %></li>
80
+ <%- end %>
81
+ </ul>
82
+ </p>
83
+ ```
84
+
85
+ Save the file and refresh the Show view for a book. Now authors show up as a list of values.
86
+
87
+ ### Step 5: Allow Create and Update views to display Authors as a multi-valued field
88
+
89
+ The `_form` partial defines the guts of the form that's used in both the `new` (Create) view and the `edit` (Update) view. That makes our lives simpler because we only have to update that one file to fix both pages!
90
+
91
+ In `app/views/books/_form.html.erb` find the lines that display the author field.
92
+
93
+ ```erb
94
+ <div class="field">
95
+ <%= f.label :author %><br />
96
+ <%= f.text_field :author %>
97
+ </div>
98
+ ```
99
+
100
+ Replace those lines with something that iterates over the values from `@book.author` and displays a text_field tag for each of them. Note that the @name attribute will be set to "book[author][]". The trailing `[]` in the name tells Rails that this is a multivalued field that should be parsed as an Array.
101
+ ```erb
102
+ <%= f.label :author, "Authors" %>
103
+ <% @book.author.each do |author| %>
104
+ <div class="field">
105
+ <%= text_field_tag "book[author][]", author %>
106
+ </div>
107
+ <% end %>
108
+ ```
109
+
110
+ This handles displaying existing author values, but what about setting the author value in the first place? If there are no values in the array, no fields are going to be displayed. As a stop-gap, we can add a conditional clause that displays an empty text_field when the array is empty.
111
+
112
+ ```erb
113
+ <%= f.label :author, "Authors" %>
114
+ <% @book.author.each do |author| %>
115
+ <div class="field">
116
+ <%= text_field_tag "book[author][]", author %>
117
+ </div>
118
+ <% end %>
119
+ <%- if @book.author.empty? %>
120
+ <div class="field">
121
+ <%= text_field_tag "book[author][]", nil %>
122
+ </div>
123
+ <%- end %>
124
+ ```
125
+
126
+ *Note:* This still doesn't cover the case where you want to _add_ more than one Author to a Book. That goes beyond the scope of this tutorial because it requires javascript (or a multi-page workflow).
127
+
128
+ > #### Rails 4-only step
129
+ >
130
+ > Update the `book_params` method in `app/controllers/books_controller.rb` from
131
+ > ```ruby
132
+ > def book_params
133
+ > params.require(:book).permit(:title, :author)
134
+ > end
135
+ > ```
136
+ > to
137
+ > ```ruby
138
+ > def book_params
139
+ > params.require(:book).permit(:title, :author=>[])
140
+ > end
141
+ > ```
142
+
143
+ ### Step 6: Try out multiple authors
144
+
145
+ Start up the rails console and run the following commands to add a second author to our book.
146
+
147
+ ```ruby
148
+ b = Book.find('changeme:1')
149
+ b.author += ['Some other author']
150
+ b.save
151
+ ```
152
+
153
+ Visit [[http://localhost:3000/books]] again and see that multiple authors show up and that you can edit them.
154
+
155
+ ### Step 7: Commit your Work
156
+
157
+ ```text
158
+ git add .
159
+ git commit -m "Handling multivalued author fields"
160
+ ```
161
+
162
+ ### Step 8: [Optional] Enhance the display of Title fields
163
+
164
+ Based on the concepts in steps 1-7, determine whether you want 'Title' to display as a single or multi-valued field and make appropriate edits to the 'show' view and '_form' partial on your own.
165
+
166
+ # Next Step
167
+ Proceed to [[Lesson: Set up your Rails Application to use RSpec]] or explore other [Dive into Hydra](Dive into Hydra#Bonus) tutorial bonus lessons.