表单更改一个变量

时间:2014-11-02 18:57:40

标签: ruby-on-rails checkbox form-for

我有一个包含项目列表的表格;表格的一列提供了一个检查项目的机会,因为"已完成。"我正在使用f.check_box和f.submit。表单认为它是保存的,但它根本不会影响数据库中的项目。

我的观看代码是:

<td><div><%= form_for [t] do |f| %>
        <%= f.check_box :completed, {}, "true" %>
        <%= f.submit 'Save' %>
      <% end %></div></td>

我的控制器代码是:

def update
    @todo = Todo.find params[:id]
    if @todo.save 
      redirect_to :back
      flash[:notice] = "Success!"
    else
      redirect_to :back
      flash[:notice] = "Please try again."
    end
end

单击复选框并单击该行&#34;&#34; Save&#34;按钮,我被重定向回列表并获得成功!&#34;消息,但数据库中没有发生任何事情。

我唯一能想到的是,当我在列表中查看源代码时,复选框会调用两种不同的方法,&#34; post&#34;和&#34;补丁&#34;。我必须在routes.rb中创建PATCH路由,否则复选框根本不会解决:

<form accept-charset="UTF-8" action="/todos/53" class="edit_todo" id="edit_todo_53"         method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /><input name="_method" type="hidden" value="patch" /><input name="authenticity_token" type="hidden" value="gUQ5ByGVYFncKW+6Rd/hYqiRE+DV5B1IS88EG1hZbBo=" /></div>

2 个答案:

答案 0 :(得分:0)

update行动中你应该:

def update
  @todo = Todo.find params[:id]
  if @todo.update todo_params 
    # ...
  end
end

private 

def todo_params
  # ...
end

save仅保留当前状态@todo,但在任何地方都没有更改。

PS。我假设你至少使用Rails 4.0

答案 1 :(得分:0)

对象未更改的原因是因为根本没有代码来指示对象被更改。

def update
  @todo = Todo.find params[:id]
  if @todo.save 

在这里你获取对象,然后你保存它,但你不能修改它。

您可以将操作更改为使用update而不是save,并从表单中传递新值。

def update
  @todo = Todo.find(params[:id])
  if @todo.update(params[:todo])
    # ...
  else
    # ...
  end
end

但是,这将允许用户可能更改对象中的任何字段。因此,您只需要过滤允许的字段。

def update
  @todo = Todo.find(params[:id])
  if @todo.update_attribute(todo_params)
    # ...
  else
    # ...
  end
end

def todo_params
  params.require(:todo).permit(:completed)
end

或使用特定的单一更新

def update
  @todo = Todo.find(params[:id])
  if @todo.update_attribute(todo_params[:completed])
    # ...
  else
    # ...
  end
end

def todo_params
  params.require(:todo)
end

最后但同样重要的是,使用自定义模型方法可以使您的控制器更易于维护和测试。