Alessio Caiazza is sharing code with you

Bitbucket is a code hosting site. Unlimited public and private repositories. Free for small teams.

Don't show this again

nolith / habtm-with-deferred-save

Rails plugin. Defers saving the records you add to habtm association until you call model.save, allowing validation in the style of normal attributes.

Clone this repository (size: 195.2 KB): HTTPS / SSH
hg clone https://bitbucket.org/nolith/habtm-with-deferred-save
hg clone ssh://hg@bitbucket.org/nolith/habtm-with-deferred-save
commit
bfd249c9ea1e
parent
7abf2daec757
branch
default

git-svn-id: https://habtm-with-deferred-save.googlecode.com/svn/trunk@4 e8f5f159-813c-0410-8c33-cd1931e36101

1
ac95efc9417b
=has_and_belongs_to_many_with_deferred_save
2
ac95efc9417b
3
ac95efc9417b
==Example
4
ac95efc9417b
5
ac95efc9417b
Room has_and_belongs_to_many_with_deferred_save People
6
ac95efc9417b
7
bfd249c9ea1e
Lets say you want to validate the room.people collection and prevent the user from adding more people to the room than will fit. If they do try to add more people than will fit, you want to display a nice error message on the page and let them try again...
8
ac95efc9417b
9
bfd249c9ea1e
This isn't possible using the standard has_and_belongs_to_many due to these two problems:
10
ac95efc9417b
11
bfd249c9ea1e
1. When I do the assignment to my collection (room.people = whatever), it immediately saves it in my join table (people_rooms) rather than waiting until I call room.save.
12
ac95efc9417b
13
bfd249c9ea1e
2. You can "validate" using habtm's :before_add option ... but it any errors added there end up being ignored/lost. The only way to abort the save from a before_add seems to be to raise an exception... 
14
ac95efc9417b
15
bfd249c9ea1e
We don't want to raise an exception when the user violates my validation. We want validation of the people collection to be handled the same as any other field in the Room model: We want it to simply add an error to the Room model's error array which we can than display on the form with the other input errors.
16
ac95efc9417b
17
bfd249c9ea1e
has_and_belongs_to_many_with_deferred_save solves this problem by overriding the setter method for your collection (people=), causing it to store the new members in a temporary variable (unsaved_people rather than saving it immediately.
18
ac95efc9417b
19
ac95efc9417b
You can then validate the unsaved collection as you would any other attribute, adding to self.errors if something is invalid about the collection (too many members, etc.).
20
ac95efc9417b
21
ac95efc9417b
The unsaved collection is automatically saved when you call save on the model.
22
ac95efc9417b
23
ac95efc9417b
==Project home
24
ac95efc9417b
25
ac95efc9417b
http://code.google.com/p/habtm-with-deferred-save/
26
ac95efc9417b
27
ac95efc9417b
==History
28
ac95efc9417b
29
ac95efc9417b
It started as a post to the Rails mailing list asking how to validate a has_and_belongs_to_many collection/association (see http://www.ruby-forum.com/topic/81095).
30
ac95efc9417b
31
ac95efc9417b
==Copyright
32
ac95efc9417b
33
ac95efc9417b
2007 (c) QualitySmith, Inc.