Jean-Daniel Beaubien
2006-Jul-02 06:11 UTC
[Rails] Problems implementing a N:M table that contains actual data
Hi everyone, I''m currently finishing the planning phase of a small project I want to create. I read a bunch of tutorials about ActiveRecord and the different way to link your "tables" with belongs_to, has_many, has_and_belong_..., etc... However I''m stillnot sure if what I''m trying to do will work *well* with ActiveRecord. So enough talk, here''s what i''m trying to do. +-------+ +-------------+ +-----+ |clients|----------|clients_steps|-------------|steps| +-------+ +-------------+ +-----+ |id | |client_id | |step_id | |completed_at | +-------------+ | +--------------+ |documents | +--------------+ |client_step_id| | more | | fields | +--------------+ So we have clients, and we have steps. Each client has a bunch of steps (many-to-many relationship). The thing is each step is completed by a client at a certain date, which is logically stored in the clients_steps. Now I''ve never seen anything talking about using data from a N:M table, I''ve only seen it used purely as associative (it''s main purpose). Is there a way to easily access fields in a many to many table (has_and_belongs_to_many_thingy)??? Secondly, some steps require certain documents. These documents are specific per step and per client. So logically they should be attached to the clients_steps. At this point I have absolutely no idea even where to start in Rails on how to do this. I am new to Rails, so I need a bit of help to figure this out. Any tip / recommendation would be greatly appreciated. Thanks, Jd P.S. If I have do, I''ll do pure SQL. I''m just wondering if there''s a clean way to implement this in the "Rails way".
Chris Carter
2006-Jul-02 14:33 UTC
[Rails] Re: Problems implementing a N:M table that contains actual d
What you want is a "has_many through" association. First, rename the join to something like "stepping" and create a model file for it. class Client < ActiveRecord::Base has_many :steppings has_many :steps, :through => steppings end same thing for steps but wwith client instaed of steps in the has_many. class Steppings < ActiveRecord::Base belongs_to :clients belongs_to :steps has_many :documents end Hope that helps! -- Posted via http://www.ruby-forum.com/.
Jean-Daniel Beaubien
2006-Jul-02 18:05 UTC
[Rails] Re: Problems implementing a N:M table that contains actual d
Thank you very much, this has helped me alot. Unfortunatley I''ve hit another snag. I''ve manage to create all my tables through migration and now all my models seem to be working correctly when I play with my objects in the console. But now, I want to associated all the steps to a client on creation of that client, and I can''t find a way to do that. I''ve read the small many-to-many relationship tutorial at http://jrhicks.net/Projects/rails/has_many_and_belongs_to_many.pdf. Unfortunately I couldn''t get it to work properly. Here''s what I tried (I have the models that are shown in the quoted text plus the Step one) ----------------------------------------- class Step < ActiveRecord::Base has_many :steppings has_many :clients, :through => :steppings end ----------------------------------------- class ClientsController < ApplicationController <snip>... def new @client = Client.new end def create @client = Client.new(params[:client]) @steps = Step.find_all <------------------------ Here''s where the magic @client.steps = @steps <------------------------ doesn''t happen if @client.save flash[:notice] = ''Client was successfully created.'' redirect_to :action => ''list'' else render :action => ''new'' end end <snip>... end ----------------------------------------------- This code would give be an error saying that Client did not have a step method, so I added one: ------------------------------- class Client < ActiveRecord::Base <snip>... def steps=(new_steps) @steps = new_steps end end ------------------------------ No more errors, but nothing in the database was added either. I also tried changing the code in the controller: @client.steps= @steps becomes @client.steppings = @steps But that did not work either. The error tells me: Expecting steppings, getting steps. I am pretty lost at the moment, since I have no idea how to populate this association. Any help would, once again, be greatly appreciated, Thank you, -- Jean-Daniel Chris Carter wrote:> What you want is a "has_many through" association. First, rename the > join to something like "stepping" and create a model file for it. > > class Client < ActiveRecord::Base > has_many :steppings > has_many :steps, :through => steppings > end > > same thing for steps but wwith client instaed of steps in the has_many. > > class Steppings < ActiveRecord::Base > belongs_to :clients > belongs_to :steps > has_many :documents > end > > Hope that helps! > >