(The subject is in reference to page 241 of the Rails book.) I''m trying to determine a best practice as far as this situation is concerned -- that is, when you have a table that functions as both a join table and a model in its own right (this concept is described in the rails book). For those unfamiliar, take for example, the following simple habtm relationship: users, games_users, games A user can compete in many games. A game can have many competitors. The "games_users" join table is effectively a "competitors" table. You maybe want to add on some additional attributues to it like "current_score", "competitor nickname". Etc. All that is possible with HABTM relations. But now what if I really do want this "competitors" table to function like a model too: Let''s say for example, I want to start throwing in some tables to describe or reference the "competitor" -- maybe the competitor has some game state - like a "moves" table to describe all the moves the competitor has done in that game. Now it''s truly like a model and I''d want to say things like "competitor.moves" What are my options? 1. Treat it like a model (as the rails book suggests) and write custom find methods in User and Games to achieve habm behavior (book doesn''t have anything to say about that last part) 2. Treat it like a habtm and use "composite foreign keys" in tables like "moves" (user_id, game_id in moves table) 3. Try to do some rails trickery so that it can be both. Instead of naming the primary key of the join table "id", name it "competitor_id" and establish both has_many and habtm relationships. I''d be curious to know if this actually works -- never tried it myself. The downside of this is that now we''re beginning to let rails implementation details affect database decisions. That seems like a no no. Does anybody have any experience or opinions on this matter? Either generally or specifically.
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Oct 5, 2005, at 1:57 PM, Noah Davis wrote:> 1. Treat it like a model (as the rails book suggests) and write custom > find methods in User and Games to achieve habm behavior (book doesn''t > have anything to say about that last part) > 2. Treat it like a habtm and use "composite foreign keys" in tables > like "moves" (user_id, game_id in moves table) > 3. Try to do some rails trickery so that it can be both. Instead of > naming the primary key of the join table "id", name it "competitor_id" > and establish both has_many and habtm relationships. I''d be curious to > know if this actually works -- never tried it myself. The downside of > this is that now we''re beginning to let rails implementation details > affect database decisions. That seems like a no no.I prefer 1, though 3 is cool too. Remember that you have eager loading (the :include option to the find methods) at your disposal. Best, jeremy -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.2 (Darwin) iD8DBQFDREHjAQHALep9HFYRAivlAKCXPzeo93ISjR2i3visgSOgTqDvqwCfboQ5 8kM6o7VOA+5bCtCuNdtsJyw=mmjN -----END PGP SIGNATURE-----
On 5-okt-2005, at 23:13, Jeremy Kemper wrote:> -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA1 > > On Oct 5, 2005, at 1:57 PM, Noah Davis wrote: > > I prefer 1, though 3 is cool too. Remember that you have eager > loading > (the :include option to the find methods) at your disposal.What I do currently is assign a "railified" name to the join table right off the start, so that I can convert it to a full-fledged model later on. For instance, in a recent project I have people that can have many skills. Thus, the following emerges: Person >-< Skill. Between these I put "capabilities" as a join table, so that later I can extend it to be a model on it''s own (for now I don''t need any extra attributes there, but you never know). After that (and after defining Capability) I can grab the attrfibute assignment methods from Skill and import them into my future Capability model, so that it builds a relevant Skill _inside_itself_ when needed. I am sure someone can provide the code for that - something like. You can also write some boilerplate stuff that will collect validation errors from the underlying association. class Capability for col Skill.content_columns class_eval do def #{col}=(new_value) #lookup existing skill or create a new one and associate it with self end def #{col} skill ? skill.send(:#{col}) : nil # get an attribute from Skill end end end end OTOH, I found deeply nested associations cumbersome to edit through controllers and they are also inaccessible for the views. P.S. I remember a patch somewhere in the trac which would allow accessing associated collections from form helpers. I want this one. Badly. -- Julian "Julik" Tarkhanov