I have an habtm problem, which I just can''t figure out for the life of me. This is a continuation of another problem I had (on this thread: http://www.ruby-forum.com/topic/44286#9200), which someone was kind enough to help me with.) To recap, I have tables Projects and Stages, with a habtm relationship. I have a table Projects_Stages contains project_id, stages_id and an additional date_done field (containing the date the stage of the project was completed). In addition to letting the user select the next stage of the project, I want them to be able to select the date that stage was completed, so I need a date select field on the page. My models: class Stages < AR has_and_belongs_to_many :projects end class Projects < AR has_and_belongs_to_many :stages attr_accessor :newly_completed_stage_id attr_accessor :stage_date_done def before_save stages.push_with_attributes(Stage.find(newly_completed_stage_id.to_i), :date_done => stage_date_done) unless newly_completed_stage_id.blank? end end My edit.rhtml page contains (as part of the form_tag): <%= collection_select(:project, :newly_completed_stage_id, Step.find(:all) - @project.stages, :id, :description, {:include_blank => true}) %> <%= date_select (:project, :stage_date_done, :order => [:day, :month, :year]) %> The collection_select works just fine on its own. However, adding the date_select to the edit.rhtml page as shown above, returns the following error: undefined method `klass'' for nil:NilClass Trace shows parameters are being passed (some data omitted): Parameters: {"commit"=>"Save", "id"=>"1", "project"=>{"stage_date_done(3i)"=>"13", "newly_completed_step_id"=>"5", "stage_date_done(1i)"=>"2005", "stage_date_done(2i)"=>"12"}} If I omit the date_select command in edit.rhtml and change my before_save method to ":date_done => Date.today", then everything works properly. So the problem is with the date_select command or the stage_date_done attribute. But I can''t find anything wrong with it, and I can''t find any information on what the ''klass'' method is. So I''m stuck! Is this just an habtm limitation or am I missing something? The only thing I can think of is that date_select returns an array (as evidenced by the parameters passed), and that maybe I need to somehow define stage_date_done as an array using attr_accessor? However, I can''t find any way to do this (I have both the Programming Ruby and Agile books). Thanks! -- Posted via http://www.ruby-forum.com/.
zero halo wrote:> ... > attr_accessor :stage_date_done > ... > <%= date_select (:project, :stage_date_done, :order => [:day, :month, > :year]) %> > > The collection_select works just fine on its own. However, adding the > date_select to the edit.rhtml page as shown above, returns the following > error: > > undefined method `klass'' for nil:NilClass > ... > > The only thing I can think of is that date_select returns an array (as > evidenced by the parameters passed), and that maybe I need to somehow > define stage_date_done as an array using attr_accessor? However, I can''t > find any way to do this (I have both the Programming Ruby and Agile > books).There is no way for Rails to know that stage_date_done is of class Date, so multi-parameter assignments from posted parameters only work with database columns where the type can be determined. Possible solutions: 1. Extract the parameters manually, perhaps making use of AR''s extract_callstack_for_multiparameter_attributes method. 2. Somehow instantiate stage_date_done as a column in a way that Rails knows it''s not database-backed. 3. Instantiate stage_date_done as Date.new, and patch Rails around http://dev.rubyonrails.org/browser/trunk/activerecord/lib/active_record/base.rb#L1690 to look for the class of non-column attributes. -- We develop, watch us RoR, in numbers too big to ignore.
Mark Reginald James wrote:> 1. Extract the parameters manually, perhaps making use of AR''s > extract_callstack_for_multiparameter_attributes method.Best way to do this would probably be to use select_year, select_month, and select_day, use their field_name options, and three attr_accessors. -- We develop, watch us RoR, in numbers too big to ignore.
Mark Reginald James wrote:> Best way to do this would probably be to use select_year, > select_month, and select_day, use their field_name options, > and three attr_accessors. >Yep, tried that and it worked! I set each select_xxx with :prefix=>:project, :field_name=>:stage_xxx then created attr_accessor :stage_day, :stage_month, :stage_year and finally changes before_save to: def before_save stagedate = (stage_year + stage_month + stage_day).to_date stages.push_with_attributes(Stage.find(newly_completed_stage_id.to_i), :date_done => (stagedate)) unless newly_completed_stage_id.blank? end Interesting is that :date_done => stagedate returns a strange error (''unknown method < in Nil''). Only :date_done => (stagedate) works. Sure would be nice though if habtm had a way of verifying the attribute type in this sort of situation. Maybe Rails could be patched so that attr_accessor would accept a variable type? Thanks a lot, Mark, for your help. It''s almost taken me a long to try to solve this one little problem as to write my whole app! -- Posted via http://www.ruby-forum.com/.
zero halo wrote:> def before_save > stagedate = (stage_year + stage_month + stage_day).to_date > stages.push_with_attributes(Stage.find(newly_completed_stage_id.to_i), > :date_done => (stagedate)) unless newly_completed_stage_id.blank? > end > > Interesting is that :date_done => stagedate returns a strange error > (''unknown method < in Nil''). Only :date_done => (stagedate) works.stagedate = Date.new( stage_year, stage_month, stage_day ) would be better.> Sure would be nice though if habtm had a way of verifying the attribute > type in this sort of situation. Maybe Rails could be patched so that > attr_accessor would accept a variable type?Yes, I think Rails should allow models to define both DB-backed and non-DB-backed columns, so that both types can make use of validations and multi-parameter assignments. -- We develop, watch us RoR, in numbers too big to ignore.