我有一个包含项目列表的表格;表格的一列提供了一个检查项目的机会,因为"已完成。"我正在使用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="✓" /><input name="_method" type="hidden" value="patch" /><input name="authenticity_token" type="hidden" value="gUQ5ByGVYFncKW+6Rd/hYqiRE+DV5B1IS88EG1hZbBo=" /></div>
答案 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
最后但同样重要的是,使用自定义模型方法可以使您的控制器更易于维护和测试。