使用rails 3以内部形式更新嵌套表单和现有数据

时间:2011-03-22 22:54:56

标签: ruby-on-rails ruby ruby-on-rails-3 associations nested-forms

我正在尝试让嵌套表单视图正确更新。但是,当第二种形式存在数据时,这会导致问题。

我正在使用accepts_nested_attributes_for和nested_form_for。第二个目的是使用js动态添加表单元素。见github for more

我得到的错误是:

Couldn't find Muscle with ID=3685340 for Exercise with ID=212831413

我已尝试手动进行更新,但我的代码并没有真正起作用,而且我的印象是它不应该被需要,因为rails假设在引擎盖下处理它。

这个想法是:练习通过目标有很多肌肉 从练习形式中我希望能够添加目标肌肉。

我的模特:

class Exercise < ActiveRecord::Base
  has_many :targets, :dependent => :destroy
  has_many :muscles, :through => :targets
  accepts_nested_attributes_for :muscles, :reject_if => :all_blank
  ...
end

class Target < ActiveRecord::Base
  belongs_to :exercise
  accepts_nested_attributes_for :exercise, :update_only => true
  belongs_to :muscle
end

class Muscle < ActiveRecord::Base
  has_many :targets, :dependent => :destroy
  has_many :exercises, :through => :targets
end

我的(haml)观点:

%p
  %b Target(s):
  = f.fields_for :muscles do |e|
    = e.collection_select :id, Muscle.all, :id, :name
    = e.link_to_remove "-remove"
  = f.link_to_add "Add target muscle", :muscles

最后我的失败控制器:

  def update
    @exercise = Exercise.find(params[:id])
    @exercise.user = current_user

    params[:exercise][:muscles_attributes].each { |id, muscle|
    target = Target.where(:exercise_id => @exercise.id , :muscle_id => muscle[:id]).first
    if target && !(muscle[:_destroy] == "false")
      puts "!!>>>>>>>>>>>>>>>>>>destroy target #{target.exercise_id} #{target.muscle_id}"
      target.destroy
    else
      if !target
        t = @exercise.targets.build(:muscle_id => muscle[:id])
        t.save
      end
    end
  }

  respond_to do |format|
    if @exercise.update_attributes(params[:exercise])
      format.html { redirect_to(@exercise, :notice => 'Exercise was successfully updated.') }
      format.xml  { head :ok }
    else
      format.html { render :action => "edit" }
      format.xml  { render :xml => @exercise.errors, :status => :unprocessable_entity }
    end
  end
end

请告诉我是否应该公开更多我的代码(无论如何最终结果将是开源),请尽快向github或其他任何请求致谢,提前感谢。

1 个答案:

答案 0 :(得分:0)

您可以通过操作中间表(targets

来实现此目的

在模型中插入:

accepts_nested_attributes_for :targets

在你的html中,用javascript附加这一行:

<input name="exercise[targets_attributes][0][muscle_id]" value="the_muscle_id_goes_here" type="hidden">