On Wed, Feb 15, 2012 at 10:13 AM, Bodo Kist <[email protected]> wrote:
> Hello, > > I'm trying to solve a common task with many to many relationships. > > Here are my class definitions: > > class User < ActiveRecord::Base > has_many :questionnaires > has_many :forms, :through => :questionnaires > end > > class Form < ActiveRecord::Base > has_many :questionnaires > has_many :users, :through => :questionnaires > end > > class Questionnaire < ActiveRecord::Base > belongs_to :user > belongs_to :form > end > > My problem is to include an extra date field named active_at to User > new/edit form. > > When creating a user I need to check forms (via checkboxes) which it > belongs to. I know it can be done by creating checkboxes with name like > 'user[form_ids][]'. But I also need to enter a date field for each of > checked relations which will be stored in the questionnaire join model. > > Any help is very appreciated > We recently had a long (and confusing) discussion about this https://groups.google.com/forum/#!topic/rubyonrails-talk/W-FTZNPNUeE/discussion Looking back at it, I would suggest take it step-by-step. Try first to understand how to get it to work on the model level, write unit tests for that and only after that, build your new/edit view code that will generate the params hash that will fill in the values. There is a good chance you will need to do some "manual" tweaking to completely build up the datastructure from the params hash. I mean a simple user = create(params[:user]) may require you defining some additional setter methods. Maybe, the core is that you will need to override the form_ids=(id,id,...) method on the User model (start with rails c > User.new.methods.grep(/form_ids=/) to see if it is defined. Assuming you use Rails 3.2.x you could start playing with (UNTESTED code, probably not optimal, just a hint): class Questionnaire < ActiveRecord::Base belongs_to :user, :inverse_of => :users belongs_to :form, :inverse_of => :forms # important for the save after build ! # google this line: "The last line ought to save the through record (a Taggable). This will only work if the :inverse_of is set:" end class User < ActiveRecord::Base has_many :questionnaires has_many :forms, :through => :questionnaires def form_ids=(form_id_array) super # will pass the argument to higher-up function and build the associated forms self.forms.each do |form| # I presume this will be populated by now qs = form.questionnaires qs = qs.select{|q| q.user == self} # filter only those that are this user raise "BOOOM" if qs.size > 1 # there can be only 1 (check it to be sure) q = qs.first q.active_at Time.now end end end Then check the result manually and with tests. Then save the user and check if all is still correct. Once you can set the active_at to Time.now, a next phase can start to set it to actual values, that are gotten from the form (probably need to make a non-standard input format that may be an array of hashes with in each entry the form_id and the date for that form_id ??). I hope this helps, but I keep finding this non-trivial ... If I overlook the obvious, standard solution, I would be glad to be corrected. Peter -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.

