Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails Rails的“编辑”操作无法使用同一模型的多个实例正确填充表单_Ruby On Rails_Ruby_Forms - Fatal编程技术网

Ruby on rails Rails的“编辑”操作无法使用同一模型的多个实例正确填充表单

Ruby on rails Rails的“编辑”操作无法使用同一模型的多个实例正确填充表单,ruby-on-rails,ruby,forms,Ruby On Rails,Ruby,Forms,我是Rails新手,正在做我的第一个项目。另外,英语不是我的母语,所以请容忍我 我遇到的问题是,我有一个表单,该表单具有同一模型的多个实例,数据创建正确,但当我尝试编辑它时,表单以错误的方式填充 我正在制作一个应用程序来检查一切是否符合规则。 要检查的项目位于嵌套的关联章->子章->检查中 每次提交检查时,都会创建一个检查轮,并且每次检查的信息都会单独存储在检查结果中 查房 has_many :check_results, inverse_of: :check_round, dependent:

我是Rails新手,正在做我的第一个项目。另外,英语不是我的母语,所以请容忍我

我遇到的问题是,我有一个表单,该表单具有同一模型的多个实例,数据创建正确,但当我尝试编辑它时,表单以错误的方式填充

我正在制作一个应用程序来检查一切是否符合规则。 要检查的项目位于嵌套的关联章->子章->检查中

每次提交检查时,都会创建一个检查轮,并且每次检查的信息都会单独存储在检查结果中

查房

has_many :check_results, inverse_of: :check_round, dependent: :destroy
accepts_nested_attributes_for :check_results, reject_if: proc { |att| att['observation'].blank? }
检查结果

belongs_to :check_round, optional: true, inverse_of: :check_results
belongs_to :check
章节

has_many :subchapters
分章

belongs_to: chapter
has_many: checks
检查

belongs_to :subchapter
has_many :check_results
该表单显示所有章节以及嵌套的子章节和检查。 每个检查都显示其名称,并有一个文本区域作为输入

用户可以填写一张或多张支票

<%= form_for(@check_round, :url => {:action => 'update', :client_id => @client.id, :project_id => @project.id}) do |f| %>
  <% @chapters.each do |chapter| %>
    <%= chapter.name %>
    <% chapter.subchapters.each do |subchapter| %>
      <%= subchapter.name %>
      <% subchapter.checks.each do |check| %>
         <%= f.fields_for :check_results do |result| %>
            <%= check.name %>
            <%= result.hidden_field(:check_id, :value => check.id) %>
            <%= result.text_area(:observation, rows: 4, :id =>'obs' + check.id.to_s) %>
        <% end %>
      <% end %>
   <% end %>
  <% end %>
<% end %>
例如,如果我在编辑时提交
check.id=3
具有
observation=“bad”
,则无论其id如何,每个检查的观察值都具有“bad”

我想知道如何在“编辑”中显示除已创建的检查之外的所有空白检查


提前感谢您的时间

我相信它可以像您希望的那样工作(代码经过一些简化):

检查

edit.html.erb

<%= form_for(@check_round, :url => {:action => 'update'}) do |f| %>
  <ul>
    <% @chapters.each do |chapter| %>
      <li>
        <%= chapter.name %>
        chapter
        <ul>
          <% chapter.subchapters.each do |subchapter| %>
            <li>
              <%= subchapter.name %>
              subchapter
              <ul>
                <% subchapter.checks.each do |check| %>
                  <li>
                  <%= check.name %>
                  check
                  <br>
                  <%= f.fields_for :check_results, check.check_results_for_form(@check_round.id) do |result| %>
                    <%= result.hidden_field(:check_id, :value => check.id) %>
                    <%= result.text_area(:observation, rows: 4, :id =>'obs' + check.id.to_s) %>
                  <% end %>
                  </li>
                <% end %>
              </ul>
            </li>
          <% end %>
        </ul>
      </li>
    <% end %>
  <ul>
  <%= f.submit %>
<% end %>
{:action=>'update'})do | f |%>
    • 分章
      • 检查
        支票(id)%> “obs”+支票id.to_)%>

您的问题是重复显示
检查结果的表单字段。查看视图代码的第7行:

<%= f.fields_for :check_results do |result| %>
<%= f.fields_for :check_results do |result| %>
  <% if result.object.check == check %>
    <%= result.hidden_field(:check_id, :value => check.id) %>
      <%= result.text_area(:observation, rows: 4, :id =>'obs' + check.id.to_s) %>
    <% end %>
  <% end %>
<% end %>

您也可以独立于检查、子章节和章节的循环来循环检查结果,但我假设您希望保持UI的顺序和上下文。

好的,从我看到的两件事情需要修复

首先,您的
f.fields\u用于:检查结果do |结果|
需要一个额外的参数来指定它必须修改的检查结果。。。像这样的事情:

#helpers/check_rounds_helper.rb

def edit_or_instantiate_nested_check_results(f, check_round, check, new_check_result)
  if check.check_results
    f.fields_for :check_results, check_round.check_results.where(check_id: check.id) do |result|
      result.hidden_field(:check_id, :value => check.id)
      result.text_area(:observation, rows: 4, :id =>'obs' + check.id.to_s)
    end #end for the already present check results
    # if u want to add a new check result event if the check is populated
    f.fields_for :check_results, new_check_result do |new|
      new.hidden_field(:check_id, :value => check.id)
      new.text_area(:observation, rows: 4, :id =>'obs' + check.id.to_s)
    end #end for the new check result
  else #if there is no existing check result nest a form for a new one
    f.fields_for :check_results, new_check_result do |new|
      new.hidden_field(:check_id, :value => check.id)
      new.text_area(:observation, rows: 4, :id =>'obs' + check.id.to_s)
    end #end for the new check result
  end #end if statement
end
f.fields_for:check_results,@check_round.check_results.where(check_id:check.id)do|result
在完全相同的位置,因此
check
变量指定正确的方式

2de,您需要在控制器中允许嵌套参数,以便在您提交时保存这些参数。通常,您应该在check\u round控制器中看到一个名为
check\u round\u params
的方法。 这一个必须像这样才能让一切正常工作:

  def check_round_params
   params.require(:check_round_params).permit(
   /*your needed params*/, 
   check_results_attributes: [:id, :check_id, :observation, /*all your nested params*/]
   )
  end
简而言之,您的
更新
创建
操作是根据那些允许的参数工作的,因此您需要在那里定义它们<代码>检查结果属性:
是rails理解这些参数用于嵌套模型的方式


以下是一些您可能会感兴趣的文档:

这是我承诺的解决方案

既然您已经定义了必须拒绝使用空白观察值的检查结果,并且您的erb本身会涉及很多逻辑,我会将其全部放在一个辅助方法中,以便您的erb更干净。大概是这样的:

#helpers/check_rounds_helper.rb

def edit_or_instantiate_nested_check_results(f, check_round, check, new_check_result)
  if check.check_results
    f.fields_for :check_results, check_round.check_results.where(check_id: check.id) do |result|
      result.hidden_field(:check_id, :value => check.id)
      result.text_area(:observation, rows: 4, :id =>'obs' + check.id.to_s)
    end #end for the already present check results
    # if u want to add a new check result event if the check is populated
    f.fields_for :check_results, new_check_result do |new|
      new.hidden_field(:check_id, :value => check.id)
      new.text_area(:observation, rows: 4, :id =>'obs' + check.id.to_s)
    end #end for the new check result
  else #if there is no existing check result nest a form for a new one
    f.fields_for :check_results, new_check_result do |new|
      new.hidden_field(:check_id, :value => check.id)
      new.text_area(:observation, rows: 4, :id =>'obs' + check.id.to_s)
    end #end for the new check result
  end #end if statement
end
那么在你看来,

<%= form_for(@check_round, :url => {:action => 'update', :client_id => @client.id, :project_id => @project.id}) do |f| %>
  <% @chapters.each do |chapter| %>
    <%= chapter.name %>
    <% chapter.subchapters.each do |subchapter| %>
      <%= subchapter.name %>
      <% subchapter.checks.each do |check| %>
         <%= check.name %>
         <% new_check_result = CheckResult.new(check_round_id: @check_round.id, check_id = check.id) %>
         <%= edit_or_instantiate_nested_check_results(f, @check_round, check, new_check_result) %>
      <% end %>
   <% end %>
  <% end %>
<% end %>
{:action=>'update',:client_id=>@client.id,:project_id=>@project.id})do | f |%>
应该是这样的;)。让我知道它是否成功:D


KR,

您能显示创建时触发的日志吗?插入
检查轮数
项目id
创建时
更新时
)值(31,'2017-10-06 19:05:14','2017-10-06 19:05:14')插入
检查结果
check\u round\u id
check\u id
correct
观察
风险
创建时间
更新时间
)值(179,1,'No',asdfadfa',Medio',2017-10-06 19:05:14',2017-10-06 19:05:14')插入
检查结果
check\u round\u id
check\u id
correct
观察
风险
创建时间
更新时间
)值(179,15,'No',asdfasdfas',Bajo 2017-10-06 19:05:14',2017-10-06 19:05:14')如果我在同一轮检查中填写两个检查,那么数据就是这样保存的。一轮检查,然后每次填写一个检查结果。@leogar07有没有对您有用的答案?如果有,请向上投票或接受。谢谢您好,谢谢您的回答。我没有把它放在这里,但我已经有嵌套的参数。您的解决方案只显示包含c的检查检查结果。我希望得到所有的检查结果,但是只有那些有检查结果的字段才填充,其余的字段应该是空的。再次感谢你的帮助!好的,我现在得到了你想要的结果…我今天晚些时候会编辑我的答案。简言之,我要做的是一个if check\u result语句。如果check.check\u result,然后修改e现有参数,如果为false初始化局部变量new_result=CheckResult.new…今天晚些时候会更清楚xD.U也应该编辑您的问题,这样我们就知道您的嵌套参数是正确的。我尝试了您的解决方案,得到了一个:“未定义的方法` where'for#”.Usuario相当于这个问题的检查结果。@GiovanniDiToro很抱歉回答得太晚……你找到问题的解决方案了吗?我想你可能在一个实例上使用了“where”方法……嗨,Patrick!一年多后我回来了,所以
#helpers/check_rounds_helper.rb

def edit_or_instantiate_nested_check_results(f, check_round, check, new_check_result)
  if check.check_results
    f.fields_for :check_results, check_round.check_results.where(check_id: check.id) do |result|
      result.hidden_field(:check_id, :value => check.id)
      result.text_area(:observation, rows: 4, :id =>'obs' + check.id.to_s)
    end #end for the already present check results
    # if u want to add a new check result event if the check is populated
    f.fields_for :check_results, new_check_result do |new|
      new.hidden_field(:check_id, :value => check.id)
      new.text_area(:observation, rows: 4, :id =>'obs' + check.id.to_s)
    end #end for the new check result
  else #if there is no existing check result nest a form for a new one
    f.fields_for :check_results, new_check_result do |new|
      new.hidden_field(:check_id, :value => check.id)
      new.text_area(:observation, rows: 4, :id =>'obs' + check.id.to_s)
    end #end for the new check result
  end #end if statement
end
<%= form_for(@check_round, :url => {:action => 'update', :client_id => @client.id, :project_id => @project.id}) do |f| %>
  <% @chapters.each do |chapter| %>
    <%= chapter.name %>
    <% chapter.subchapters.each do |subchapter| %>
      <%= subchapter.name %>
      <% subchapter.checks.each do |check| %>
         <%= check.name %>
         <% new_check_result = CheckResult.new(check_round_id: @check_round.id, check_id = check.id) %>
         <%= edit_or_instantiate_nested_check_results(f, @check_round, check, new_check_result) %>
      <% end %>
   <% end %>
  <% end %>
<% end %>