【问题标题】:update action for multiple forms on an edit page in rails在 rails 的编辑页面上更新多个表单的操作
【发布时间】:2013-10-30 19:56:31
【问题描述】:

我有一个页面,用户可以在其中上传工作。在编辑页面上,我有一个循环遍历所有现有作业并为每个作业打印一个表单。问题是,我不知道如何告诉控制器中的更新操作要更新哪个作业。这是编辑页面:

<% @currentjobs.each do |thejob| %>
  <%= simple_form_for(thejob) do |f| %>
      <%= f.error_notification %>

      <%= f.input :firm, input_html: { class: 'field' }, label: "Firm" %> <br>
      <%= f.input :position, input_html: { class: 'field' }, label: "Position" %> <br>
      <%= f.input :category, input_html: { class: 'field' }, label: "Category"%>
      <%= f.input :begin, input_html: { class: 'field' }, label: "Beginning", collection: 1960..2013 %><br>
      <%= f.input :end, input_html: { class: 'field' }, label: "End", collection: 1960..2013 %>
      <%= f.input :description, input_html: { class: 'field' }, label: "Description"%>

         <div class="form-actions">
           <%= f.submit "Save" %>
         </div>
  <% end %>
<% end %>

这里是更新操作:

def update
        thejob = current_user.profile.jobs.where(:id => params[:id])
        thejob.update_attributes(job_params)
        flash[:success] = "You have succesfully updated your info"
        redirect_to profile_path(current_user.profile_name)
end 

我知道这与我调用表单的更新操作有关。我想我叫错了。

更新:以下是此视图生成的表单(请记住没有样式):

这是我的工作路线代码:

  resources :jobs

这里是rails生成的html:

   <h1>edit page for jobs </h1>
  <form accept-charset="UTF-8" action="/jobs/9" class="simple_form edit_job" id="edit_job_9" 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="woHDLDSOUhEA6AZU1TDVbOVW1el6lUVL3evDF/svInc=" /></div>


      <div class="input string required job_firm"><label class="string required" for="job_firm"><abbr title="required">*</abbr> Firm</label><input aria-required="true" class="string required fsield" id="job_firm" maxlength="80" name="job[firm]" required="required" size="80" type="text" value="alan iverson falkjf kjfh fsdlkjh " /></div> <br>
      <div class="input string required job_position"><label class="string required" for="job_position"><abbr title="required">*</abbr> Position</label><input aria-required="true" class="string required fsield" id="job_position" maxlength="80" name="job[position]" required="required" size="80" type="text" value="position 3" /></div> <br>
      <div class="input string optional job_category"><label class="string optional" for="job_category">Category</label><input class="string optional fsield" id="job_category" maxlength="255" name="job[category]" size="255" type="text" value="" /></div>
      <div class="input select required job_begin"><label class="select required" for="job_begin"><abbr title="required">*</abbr> Beginning</label><select aria-required="true" class="select required fsield" id="job_begin" name="job[begin]" required="required"><option value=""></option>
      <option value="1960">1960</option>
      <option value="1961">1961</option>
      .
      .
      .
      <div class="input select required job_end"><label class="select required" for="job_end"><abbr title="required">*</abbr> End</label><select aria-required="true" class="select required fsield" id="job_end" name="job[end]" required="required"><option value=""></option>
      <option selected="selected" value="1960">1960</option>
      <option value="1961">1961</option>
      .
      .
      .
      <div class="input text required job_description"><label class="text required" for="job_description"><abbr title="required">*</abbr> Description</label><textarea aria-required="true" class="text required fsield" id="job_description" maxlength="500" name="job[description]" required="required">
      </textarea></div>

  <div class="form-actions">
       <input name="commit" type="submit" value="Save" />
  </div><br><br>
</form>


<form accept-charset="UTF-8" action="/jobs/7" class="simple_form edit_job" id="edit_job_7" 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="woHDLDSOUhEA6AZU1TDVbOVW1el6lUVL3evDF/svInc=" /></div>
      <div class="input string required job_firm"><label class="string required" for="job_firm"><abbr title="required">*</abbr> Firm</label><input aria-required="true" class="string required fsield" id="job_firm" maxlength="80" name="job[firm]" required="required" size="80" type="text" value="asf asd fasf asd fas as fsaf sd" /></div> <br>
      <div class="input string required job_position"><label class="string required" for="job_position"><abbr title="required">*</abbr> Position</label><input aria-required="true" class="string required fsield" id="job_position" maxlength="80" name="job[position]" required="required" size="80" type="text" value="position 2" /></div> <br>
      <div class="input string optional job_category"><label class="string optional" for="job_category">Category</label><input class="string optional fsield" id="job_category" maxlength="255" name="job[category]" size="255" type="text" value="fafdsfds" /></div>
      <div class="input select required job_begin"><label class="select required" for="job_begin"><abbr title="required">*</abbr> Beginning</label><select aria-required="true" class="select required fsield" id="job_begin" name="job[begin]" required="required"><option value=""></option>
      .
      .
      .

      <div class="input text required job_description"><label class="text required" for="job_description"><abbr title="required">*</abbr> Description</label><textarea aria-required="true" class="text required fsield" id="job_description" maxlength="500" name="job[description]" required="required">
      </textarea></div>

         <div class="form-actions">
           <input name="commit" type="submit" value="Save" />
         </div><br><br>
</form>
.
.
.

【问题讨论】:

  • 您可以通过 URL 中的 id 参数执行此操作。您的表单的操作属性应具有类似“domain.com/jobs/:id”的值和方法 PUT 或 PATCH。由于作业 ID,Rails 知道应该更新哪个作业。但是您的代码看起来还可以吗?你的问题到底是什么?当您尝试更新作业时会发生什么?
  • 我很确定更新操作中的 :id 是指 url 中的 id。我需要以某种方式引用用户正在更新的作业的 ID 号。
  • 当我尝试更新作业时,我收到此错误:'undefined method `update_attributes' for #<:relation::activerecord_relation_job:0x007f8da290f948>'

标签: ruby-on-rails forms ruby-on-rails-4 erb simple-form


【解决方案1】:

好的,为了清楚起见,请查看 simple_form 生成的代码。它将生成多个带有 action 属性的表单,其中该属性的值类似于“domain.com/jobs/job_id”。当您提交表单时,它将从 action 属性对 URL 发出 PUT 或 PATCH 请求,这就是 Rails 知道要更新哪个作业的方式 - 因为您在 URL 中告诉它。

这对您不起作用的原因是您试图在 Relation 对象上调用方法“update_attributes”,而不是在工作中。试试这个:

thejob = current_user.profile.jobs.where(:id => params[:id]).first

甚至更好:

thejob = current_user.profile.jobs.find(params[:id)

编辑示例:

jobs_controller.rb:(我正在使用索引操作来呈现表单,但您可以使用任何您想要的操作,只是不要使用编辑 - 它应该用于编辑单个资源。)

class JobsController < ApplicationController
  def index
    @jobs = Job.all
  end

  def update
    @job = Job.find(params[:id])
    if @job.update_attributes(job_params)
      redirect_to jobs_path
    else
      render :index
    end
  end

  private

    def job_params
      params.require(:job).permit(:name)
    end
end

routes.rb:

# if you will use index action to render forms
resources :jobs


# if you want to use some custom action to render forms
# in this case add multiedit action to the jobs_controller
# and create a view for it
resources :jobs do
  get 'multiedit'
end

并查看(在我的情况下为 index.html.erb):

<% @jobs.each do |job| %>
  <%= simple_form_for(job) do |f| %>
    <%= f.input :name %>  
    <%= f.button :submit %>
  <% end %>
<% end %>

现在,视图将呈现如下内容:

<form accept-charset="UTF-8" action="/jobs/1" class="simple_form edit_job" id="edit_job_1" method="post" novalidate="novalidate">
    <input name="_method" type="hidden" value="patch" />
    .
    .
    .
</form>

<form accept-charset="UTF-8" action="/jobs/2" class="simple_form edit_job" id="edit_job_1" method="post" novalidate="novalidate">
    <input name="_method" type="hidden" value="patch" />
    .
    .
    .
</form>

这两种形式都将提交给 jobs#update 操作,但第一个带有 params[:id] == 1,第二个带有 params[:id] == 2。这就是您的需要,知道哪个对象正在被更新。希望现在清楚了...

【讨论】:

  • 谢谢,我试过了,但它会占用我更新的任何工作并且不会更新它。相反,它会使用该信息更新最后一个作业。 url 无法告诉它要更新哪个作业。该页面上有 4 个表格,每个表格对应一个不同的工作。我需要更新方法来查看填写的表格对应于哪个作业并更改该作业。该网址只是转到所有作业的编辑页面。我意识到,在看到您的回答后,也许我为此设置了错误的路线?如果是这样,我该如何解决?
  • 您能否在您的编辑视图中发布由 simple_form_for 生成的表单?并发布您的 route.rb。
  • 好的,刚刚发布了它们。谢谢。
  • 感谢您的路线。通过 simple_form 生成的表单,我指的是表单的 HTML 源代码,而不是实际的 HTML 页面。
  • 哦,好的,我现在就发布。
猜你喜欢
  • 2019-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多