ruby on rails,无法将check_box_tag值传递回update_attributes

时间:2013-12-17 18:24:29

标签: ruby-on-rails ruby checkbox update-attributes

我有一个相当简单的Rails应用程序,用数学测验做事情。用户可以通过问题和答案创建数学问题。他们还可以创建带有标题的考试。模型与has_many_and_belongs_to关系链接,因为每个测验可能有很多问题,每个问题都可以属于许多测验。这种关系似乎运作良好,因为当我删除问题或考试时,相关的对象列表会更新。我目前的方式是,当您创建考试时,视图会为您提供一个复选框列表,一个用于问题数据库中的每个问题。用户单击他们在考试中想要的问题的复选框,无论选中哪个框,这些问题都会添加到考试中。我将展示更新的代码,因为这是我用来测试的视图。

以下是观点:

  <h2>Available Problems:</h2>
  <% Problem.all.each do |prob| %>
    <%= f.fields_for "exam[problem_ids][]", prob do |builder| %>
      <p>
      <%= check_box_tag "exam[problem_ids][]", prob.id, @exam.problems.include?(prob) %>
      <%= prob.question %> = <%= prob.answer %> | <%= link_to "Edit", edit_problem_path(prob) %>
      </p>
    <% end %>
  <% end %>

我必须使用check_box_tag,因为如果我尝试使用builder.check_box,则无法保存已经检查过哪些框。

我的控制器:

  def update
    @exam = Exam.find(params[:id])

    if @exam.update_attributes(params[:exam].permit(:title, :problem_ids))
      redirect_to @exam
    else
      render 'edit'
    end
  end

在视图中,我将所有复选框结果保存在problem_ids数组中。我知道这个数组正在被正确填充,因为当我添加以下代码时,它可以正常工作。

@exam.problems = []
params[:exam][:problem_ids].each {
  |prob_id|
  @exam.problems << Problem.find(prob_id)
}

显然,这是一种非常hackey的方法,因为我每次手动构建问题列表,但我不能为我的生活弄清楚如何让那些复选框结果自动填充在{ {1}}方法。有什么想法吗?

更新: 根据Donovan的建议,我在考试模型中实施了以下方法:

update_attributes

据我了解,这应该是 def problem_ids=(some_problem_ids) @exam.problems.clear some_problem_ids.each { |prob_id| @exam.problems << Problem.find(prob_id) } end 的“setter”方法。遗憾的是,当我在考试控制器中使用以下行时,问题列表仍未更新:

problem_ids

P.S。我必须放@exam.update_attributes(params[:exam].permit(:title, :problem_ids)) 位,否则我会得到.permit(:title, :problem_ids)

2 个答案:

答案 0 :(得分:1)

@ exam.problems是一个对象列表,但由于这种关系, 也应该在您的考试中使用problem_ids setter方法,所以

@exam.update_attributes(params[:exam])

应该做你想做的事。如果由于某种原因你只需要 更新problem_ids,这应该可以解决问题:

@exam.update_attribute(:problem_ids, params[:exam][:problem_ids])

注意:我省略了rails4 strong_parameters以使rails 3或4的答案通用,请确保为您的版本使用适当的方法。

答案 1 :(得分:0)

感谢您的帮助,但我终于自己想出来了。问题是,即使我允许problem_ids作为参数传递,我也没有告诉控制器它实际上是一个数组。所以,一旦我将相关的行改为:

@exam.update_attributes(params[:exam].permit(:title, problem_ids: []))

它完美无缺!