开发者

rails validation on accepts_nested_attributes_for and habtm association in an update resets the association

In rails 2.3.8 I am having trouble with validations on a accepts_nested_attributes_for association if I loop through or even inspect the habtm association in validation the lessons are loaded and any updates are lost. For example, I have the following schema:

ActiveRecord::Schema.define(:version => 20100829151836) do

 create_table "attendees", :force => true do |t|
  t.integer  "lesson_set_id"
  t.string   "name"
  t.datetime "created_at"
  t.datetime "updated_at"
 end

 create_table "lesson_sets", :force => true do |t|
  t.datetime "created_at"
  t.datetime "updated_at"
 end 

 create_table "lesson_sets_lessons", :id => false, :force => true do |t|
  t.integer "lesson_id"
  t.integer "lesson_set_id"
 end

 create_table "lessons", :force => true do |t|
  t.integer  "activity_id"
  t.integer  "limit"
  t.datetime "created_at"
  t.datetime "updated_at"
 end
end

and the following models:

class Attendee < ActiveRecord::Base
 belongs_to :lesson_sets
end
class Lesson < ActiveRecord::Base
 has_and_belongs_to_many :lesson_sets
end
class LessonSet < ActiveRecord::Base
 has_and_belongs_to_many :lessons
 has_many :attendees
 accepts_nested_attributes_for :lessons
 validate do |lesson_set|
  lesson_set.lessons.each do |l| 
   if l.limit < attendees.count
    self.errors.add_to_base("Sorry only #{l.limit} people allowed on lesson")
   end
  end
 end
end

If I call the following:

>> ls = LessonSet.first
=> #<LessonSet id: 1, created_at: "2010-08-29 07:50:23", updated_
at: "2010-08-29 07:50:23">
>> Lesson.last
=> #<Lesson id: 1, activity_id: 29, created_at: "2010-08-29 07:57:13", updated_a
t: "2010-08-29 17:04:34", limit: 5>
params = {"lessons_attributes"=>{"0"=>{"activity_id"=>"3", "id"=>"1", "_destroy"=>""}}, "id"=>"1"}
=> {"id"=>"1", "lessons_attributes"=>{"0"=>{"activity_id"=>"3", "id"=>"1", "_des
troy"=>""}}}
>> ls.update_attributes(params)
=> true
>> Lesson.last
=> #<Lesson id: 1, activity_id: 29, created_at: "2010-08-29 07:57:13", updated_a
t: "2010-08-29 17:04:34", limit: 5>
>> params = {"lessons_attributes"=>{"0"=>{"activity_id"=>"29", "id"=>"1", "_de>
=> {"id"=>"1", "lessons_attributes"=>{"0"=>{"activity_id"=>"29", "id"=>"1", "_de
stroy"=>""}}}
>> ls.update_attributes(params)
=> true
<y_id"=>"3", "id"=>"1", "_destroy"=>""}}, "id"=>"1"}
=> {"id"=>"1", "lessons_attributes"=>{"0"=>{"activity_id"=>"3", "id"=>"1", "_des
troy"=>""}}}
>> Lesson.last
=> #<Lesson id: 1, activity_id: 29, created_at: "2010-08-29 07:57:13", updated_a
t: "2010-08-29 17:04:34", limit: 5>
>> ls.update_attributes(params)
=> true
>> Lesson.last
=> #<Lesson id: 1, activity_id: 3, created_at: "2010-08-29 07:57:13", updated_at
: "2010-08-29 17:13:36", limit: 5>

Which is basically:

the last lesson starts with an activity_id of 29

call update_attributes on the lesson_set to try and set the activity_id to 3

it re开发者_开发知识库turns true but when we look at the last lesson it has not changed

then set the activity id to be 29 ie. the same and call update_attributes

activity_id is still 29

but then call again to try and set it to 3

and this time it updates the lesson.???

Is there something wrong with my code this seems really odd behaviour to me and I cant find anything on the net similar.

think I am heading for a head slap moment!


With the models above
Lesson has_and_belongs_to_many Lesson_sets
Attendee belongs_to Lesson_set

trying to put the validation that the should not be more attendees than the limit meant that the association between the lessons and the lesson_sets was being reset during the validation before the new association was saved.

Moving the validation logic from the lesson_set to the Attendee enabled the validation to work.

So if you are having something similar try moving your validation logic from the joining model to one of the models that it joins

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜