Determine if children added/deleted in Rails Callback
Scenario:
I have a habtm relationship and would like to determine if children in one direction have been added or deleted. I'm trying to use callbacks but find i don't have a record of changes to the children. Is there something like course.students.changed?
Using:
- Rails 3.0.3
- Ruby 1.9.2p0
Tables:
students - id, first_name, last_name
courses - id, name, location courses_students - course_id, student_idModels:
class Course
# Callbacks
before_save :student_maintenance
# Relationships
h开发者_如何转开发as_and_belongs_to_many :students
protected
def student_maintenance
# I want to do something like
students.changed?
students.changes.each do |student|
if marked_for_deletion
# do something
elsif marked_for_addition
# do something else
end
end
end
end
end
class Student
# Relationships
has_and_belongs_to_many :courses
end
If you want to capture when a student has been added or removed from a course, why not use a class for the join table *courses_students*? Since that's the place where an entry will be actually created or destroyed you could easily use after_create/after_destroy callbacks in there.
Similar to polarblau's answer -- but a tad more explanation, I hope:
In textual, UML terms, the relationship might be this:
Course ------*-> Student
Read: A Course has 0 to Many Students
You can add and remove students from the association at will.
However, you are interested in knowing more about the association, that is, when the student was added or dropped from the course. This "extra" information about an association leads to discovering you need another class, a.k.a. "Association Class."
So now you would insert that class in between your existing classes as so, taking the liberty to call it a "Registration":
Course ------*->Registration------1->Student
Read: A Course has 0 to Many Registration. Each Registration must have exactly 1 Student.
The Registration class might look like this:
+--------------+
| Registration |
+--------------|
| student |
| time_added |
| time_dropped |
+--------------+
So you can easily get a list of current students for a course (where time_dropped is nil). Or a list of dropped students (where time_dropped is not nil).
精彩评论