使用不在表上的输入更新ActiveAdmin嵌套资源

时间:2015-01-18 06:06:55

标签: ruby-on-rails ruby activeadmin

我目前在我的一个activeadmin页面中有一个嵌套资源的表单:

    f.inputs "Courses" do
      f.has_many :registrations, :allow_destroy => true, new_record: true do |tc|
        tc.input :course
        tc.input :semester
      end
    end

这适用于学生资源。 学生通过注册有很多 course_offerings 。但是,我不希望用户直接从菜单中选择 course_offering (因为每年会有很多重复相同的课程)。而是有课程学期的输入。 课程学期注册模型上的实例变量。它们在表单中设置,然后在后保存挂钩中找到正确的 course_offering 并与注册相关联。代码如下:

def semester=(s)
  @semester = s.to_i
end

def semester
  self.course_offering.semester
end

def course=(co)
  @course = co.to_i
end

def course
  self.course_offering.course
end

before_save :set_course_offering

def set_course_offering
  self.course_offering = CourseOffering.where(semester_id: @semester, course_id: @course).first
  #TODO: Handle case where no course offering is found
end

我有两个问题。第一个是当注册表为空时我得到一个nil指针错误。

  

nil的未定义方法`course':NilClass

我的学生模型中有accepted_nested_attributes调用。

accepts_nested_attributes_for :registrations, :allow_destroy => true

这是我在查找错误时得到的唯一建议,但尽管有这段代码仍然可以得到它。当我删除课程学期并将其替换为 course_offering 时,似乎工作正常。

我遇到的下一个问题是,在更新后学生记录没有保存。我认为这是因为当我只更新两个课程学期实例变量时,我不会对数据库进行任何更改。我要么需要更新另一个输入,要么将调用添加到semester =方法。

1 个答案:

答案 0 :(得分:0)

您收到undefined method错误,因为当注册表为空时,没有与您的学生相关的课程产品,因此在课程的访问者方法中,您nil获得self.course_offerings。你可以尝试这个,而不考虑零值:

def course
  self.course_offering.try(:course)
end

您不需要accept_nested_attributes_for,因为您不想通过学生创建或修改课程。

对于你的第二个问题:你对脏跟踪是正确的。您的模型未保存,因为您的学生模型尚未从ActiveRecord的角度进行修改。在保存模型之前,您需要使用course_attribute_will_change!方法将属性(例如course_offering)标记为脏。

虽然这种情况看起来是引入表单对象的一个​​很好的例子。有一个很棒的图书馆叫reform