summaryrefslogtreecommitdiff
path: root/_posts/2009-04-30-relationships-in-rails-2-3.markdown
blob: 8d1b1691c36cccb831c2be144c28665931842a1e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
---
layout: post
title: Relationships in Rails 2.3
tags: [ development, rails ]
type: post
published: true
---

Ruby on Rails is becoming quite a piece of software. I've been learning how to
work with its latest version to date, 2.3, for a series of workshops on web
development. It has surprised me how easy it is now to accomplish a simple task
such as multi-model form processing. Let me show what I've been doing lately.

## Case study: a school

The example I am going to show my attendees resembles a typical school
situation. In a nutsheel:

* Students have Subjects.
* Subjects have Students.
* Students have Grades to Subjects.

![Rails relationships — student](/wp-content/uploads/2009/07/rails-relationships-student.png)

## The Models

### Student

{% highlight ruby %}
class Student < ActiveRecord::Base
   has_many :grades
   has_many :subjects, :through => :grades, :uniq => true
   accepts_nested_attributes_for :grades, :allow_destroy => true
end
{% endhighlight %}

### Subject

{% highlight ruby %}
class Subject < ActiveRecord::Base
  validates_uniqueness_of :shortname
  has_many :grades
  has_many :students, :through => :grades, :uniq => true
end
{% endhighlight %}

### Grade

{% highlight ruby %}
class Grade < ActiveRecord::Base
  belongs_to :subject
  belongs_to :student
  validates_presence_of :value
end
{% endhighlight %}

## And the magic trick!

Through `accepts_nested_attributes_for`, the student's `form_for` can now
accept nested fields through `fields_for` for setting Grades' data.

Everytime a student is created, subjects are not directly associated to him.
You need to create a form in which you allow to assign a student the subjects
you want.

[image missing]

This tells you that a student can have an array of subject id's. You even get
to see what subjects are already assigned and dissociate them just like that!
When the associations are done, a new Grade record is created to associate the
first two modules. Unfortunately, when the associations are dismantled, the
Grade association is gone too.

If you know Railscasts, the [Complex
Forms](http://railscasts.com/episodes?search=complex+forms) series explain this
task for Rails &lt; 2.3. But now it has become easier and easier to associate
models and worrying less about your structure.