- Choose two models that are related by a one-many relationship.
For example: one student can have many awards (in high school).
Student is the primary model; award is the dependent model.
Do not choose students and awards for your final project.
- Choose appropriate fields for each model.
Example:
Student |
last_name | string |
first_name | string |
birth_date | date |
gpa | float |
|
|
Award |
name | string |
year | integer |
student_id | integer |
|
Each of the models automatially contains an id, which is the primary key.
The foreign key student_id refers to id in the primary model.
- Use the scaffold software to implement the Rails models, controllers,
and views for the two model designs in 2.
Example:
create a rails project named School. Then enter these two commands:
rails g scaffold Student first_name:string
last_name:string birth_date:date gpa:float
rails g scaffold Award name:string year:integer
student_id:integer
- Establish a one-many relationship between the primary and dependent
models:
- In app/models/student.rb, add these lines inside the class definition:
# A student can have many awards.
has_many :awards
- In app/models/award.rb, add these lines inside the class definition:
# Each award is linked to a student through
# the student_id field.
belongs_to :student
- Run rake to create the database tables.
rake db:migrate
- Test your projects by starting the server and using these URLs:
http://localhost:3000/students
http://localhost:3000/awards
- Write a helper method that will be used in Part 8. It will
construct the student name by concatenating first_name and last_name.
In app/models/student.rb, add this method definition:
def name
return first_name + " " + last_name
end
- The awards form _form.html.erb is difficult to use, because it requires
knowledge of the student id field to create a new award.
Replace the id text field in the dependent model with a more helpful
dropdown menu.
Example: Replace the
following code in app/views/awards/_form.html.erb
<%= f.label :student_id %><br />
<%= f.text_field :student_id %>
with this code:
Student Name<br />
<%= f.select :student_id, @options %>
Add this code to both of the new and edit methods in the awards
controller (app/controllers/awards_controller.rb).
Add it immediately after
@award = Award.new
in the new method and immediately after
@award = Award.find(params[:id])
in the edit method.
@options = Student.find(:all,
:order => "last_name, first_name").
collect do |s|
[s.name, s.id]
end
- The index view for awards lists the student_id for each award. A more
user friendly display would list the name instead.
In the index view for the dependent model, replace the line
<td><%= award.student_id %></td>
with the line
<td><%= award.student.name %></td>
- In the show view for each item of the primary model, also
show all of the associated dependent items.
Example:
On the show view for student, write a loop that lists all of that
student's awards. Add this code to apps/views/students/show.html.erb:
<h3>Awards</h3>
<table>
<tr>
<th>Name</th>
<th>Year</th>
<th>Student</th>
</tr>
<% @student.awards.each do |award| %>
<tr>
<td><%= award.name %></td>
<td><%= award.year %></td>
<td><%= award.student.name %></td>
</tr>
<% end %>
</table>
- On the index view for student (file: app/views/students/index.html.erb)
add a column Award Count that shows the number of awards for each student.
Use this code to display the count:
<%= student.awards.count %>
- On the index page for the primary model, add a link to the
index page for the dependent model.
Example:
On the index view for students, add this link tag to the index view
for awards:
<p><%= link_to 'Awards', awards_path %></p>
See the document
Scaffold Generated RESTful Routes
for more details.
- On the index page for the dependent model, add a link to the index
page for the primary model. See the previous step for an example.
- Modify the CSS stylesheet of your project to make the fonts and colors
more interesting and/or attractive.