1

这个问题必须有一个简单的答案,但我仍然无法让它工作。

我有一个 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 相同的方式将参数中的 id 传递给控制器​​?在本例中,它是 3,但每个项目都会有所不同,因为它是在创建项目时分配的。

更新1

<%= 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 %>
4

2 回答 2

0

ProjectsController正在尝试找到正确的ProjectID,但您没有指定任何 ID。您应该id$.ajax'data值中添加一个指定项目 ID 的值,然后将 更改find为 for params[:id]

顺便说一句,您不需要额外的update_fields方法来处理对Project. Rails 会将任何PUTto路由/projects/:idProjectsController'supdate方法(假设您resources :projects在路由文件中有)。而不是指向您将使用(或您将项目存储$.ajax在其中的任何变量)并且您不必手动包含项目 ID。update_fields_projects_urlproject_url(project)

更多信息:您正在绕过 Rails 允许您更新资源的默认方式,这意味着您正在手动完成很多您不需要的工作。

在视图中,使用表单助手:

<%= 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将构建文本字段,导致控制器获取params[:project]. 您不必手动提取每个属性并应用它,您可以免费获得它。

于 2012-11-16T18:11:55.147 回答
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>
于 2012-11-16T18:31:25.693 回答