这个问题必须有一个简单的答案,但我仍然无法让它发挥作用。
我有一个Ruby On Rails应用程序,允许用户使用数据库管理项目(创建,更新,显示,编辑,销毁......等)。例如,当用户编辑项目时,她/他被带到一个页面,如http://:3000 / projects / 3 / edit,在那里她/他可以修改那里的表单。请注意,用户正在编辑此示例中的项目3。
要编辑项目,用户请单击此按钮
<td><%= button_to 'Edit', { :action => "edit", :id => project }, :method => :get %></td>
调用此方法
# GET /projects/1/edit
def edit
@project = Project.find(params[:id])
end
并且工作正常。
但是,我添加了另一个调用updateFields的方法,因此在修改字段时,会运行一个名为updateFields的javascript函数,并调用一个AJAX请求来修改表单中的其他相关字段。以下是updateFields的摘录:
<script language="JavaScript" type="text/javascript">
function updateFields(){
$.ajax({
url: "<%= update_fields_projects_url %>",
data: {
project_year: $('.project_year_class').val(),
project_type: $('.project_type_class').val(),
<snip>
}
});
}
</script>
在控制器中,我可以获得params数组中所需的所有信息,如下所示:
# PUT /projects/1
# PUT /projects/1.json
def update_fields
@project = Project.find(params[:project])
@project_year = params[:project_year]
@project_type = params[:project_type]
<snip>
respond_to do |format|
if @project.update_attributes(params[:project])
format.js
format.html
else
format.html { render :action => "update" }
format.json { render :json => @project.errors, :status => :unprocessable_entity }
end
end
end
我遇到的问题是我无法更新表单,在服务器上,我看到以下错误消息
ActiveRecord::RecordNotFound (Couldn't find Project without an ID):
app/controllers/projects_controller.rb:101:in `update_fields'
Rendered /var/lib/gems/1.8/gems/actionpack-3.2.9/lib/action_dispatch/middleware/templates/rescues/_trace.erb (1.5ms)
Rendered /var/lib/gems/1.8/gems/actionpack-3.2.9/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (2.2ms)
Rendered /var/lib/gems/1.8/gems/actionpack-3.2.9/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (10.8ms)
如果我直接指定项目ID,一切正常
@project = Project.find(3)
我的问题是如何通过javascript函数以与project_year和project_type相同的方式将params传递给控制器?在这个例子中,它是3,但它对于每个项目都是不同的,因为它是在创建项目时分配的。
UPDATE1
<%= form_for(@project, :html => {:name => "ProjectInfo"}) do |f| %>
<input type=button id=project_info_button_id value="Show Details" onclick="showHideDiv('project_info_id','project_info_button_id');">
<div class="form input", id='project_info_id', style='display:none'>
<% concat "Project Year" %>
<%= f.text_field :ProjectYear, {:class=>"project_year_class", :Size=>6, :style=>"text-align:right"} %>
<snip>
<% end %>
<% end %>
答案 0 :(得分:0)
ProjectsController
正在尝试找到正确的Project
,但您没有指定任何ID。您应该在指定项目ID的id
$.ajax
值中添加data
值,然后将find
更改为params[:id]
。
另外,您不需要额外的update_fields
方法来处理Project
的更新。 Rails会将PUT
/projects/:id
传递给ProjectsController
的{{1}}方法(假设您的路径文件中有update
)。您可以使用resources :projects
(或您存储项目的任何变量)而不是将$.ajax
指向update_fields_projects_url
,而不必手动包含项目ID。
更多相关内容:您绕过了Rails允许您更新资源的默认方式,这意味着您手动完成了大量不需要的工作。
在视图中,使用表单助手:
project_url(project)
然后您只需要处理控制器中的<%= form_for @project do |project_form| %>
<%= project_form.text_field :year %>
<%= project_form.text_field :type %>
<%= end %>
方法,该方法主要是在update
中编写的:
update_fields
当您这样做时,def update_fields
@project = Project.find(params[:id])
respond_to do |format|
if @project.update_attributes(params[:project])
format.js
format.html
else
format.html { render :action => "update" }
format.json { render :json => @project.errors, :status => :unprocessable_entity }
end
end
end
将构建文本字段,导致控制器获取form_for
内的所有内容。您不必手动提取每个属性并应用它,您可以免费获得所有属性。
答案 1 :(得分:0)
您需要在ajax请求的数据部分中传递项目ID:
<script language="JavaScript" type="text/javascript">
function updateFields(){
$.ajax({
url: "<%= update_fields_projects_url %>",
data: {
project_year: $('.project_year_class').val(),
project_type: $('.project_type_class').val(),
id: <%= @project.id %>,
<snip>
}
});
}
</script>