【问题标题】:undefined method `[]' for nil:NilClass Ruby Object in lib Rails未定义的方法 `[]' for nil:NilClass Ruby Object in lib Rails
【发布时间】:2015-05-21 19:34:03
【问题描述】:

我有一个形式相当复杂的应用程序,它使用 lib 文件夹中的 Ruby 对象(我第一次使用 ruby​​ 对象)。我无法弄清楚如何在我的更新嵌套属性表单中创建多个 :task_ids,即使参数是在我的 Ruby 对象自定义类中定义的(这是我第一次使用它,我正在学习如何调用它)。我不断收到此错误:

undefined method `[]' for nil:NilClass

我的表单试图做的是基于预制的“模板”任务和里程碑创建启动任务和启动里程碑。因此,当用户创建项目时,他们已经添加了一些常见任务。此代码直接与上一个问题和答案相关: Add Multiple Nested Attributes through checkboxes Rails 4 (maybe with multiple forms)

我的控制器:

class ProjectsController < ApplicationController

def new_milestones
    @project.milestones.build
    @project.tasks.build
    @milestones_templates = MilestoneTemplate.where(template_id: @project.template_id)
  end

 def update
    respond_to do |format|
      result = ProjectUpdater.perform(@project, update_params) == true
      if result == true
        format.html { redirect_to @project, notice: 'Project was successfully updated.' }
        format.json { render :show, status: :ok, location: @project }
      else
        @project = result
        format.html { render :edit }
        format.json { render json: @project.errors, status: :unprocessable_entity }
      end
    end
  end

  def project_params
      params.require(:project).permit(:id, :name, :template_id, milestone_attributes:[{:names => []},  {:ids => []}, { :milestone_ids => []},:id, :name, :project_id, :milestone_template_id, :project_id, task_attributes: [{:names => []},  {:ids => []}, { :task_ids => []}, :id, :name, :milestone_id, :task_template_id, :project_id, :_destroy]])
    end
  end

lib/project_updater.rb

class ProjectUpdater

  def self.perform(project, params)
    **milestones = params[:project][:milestones]** <--- this is the line where the error is
    #Create and save each milestone
    # You might be able to us nested attributes to save tasks.

    if project.update_attributes(params[:project])
      return true
    else
      return project
    end
  end
end

我的表格

<%= form_for @project do |f| %>
  <% @milestones_templates.each_with_index do |milestone, index| %>
    <br>
    <%= f.fields_for :milestones, index: index do |fm| %>
      <%= fm.hidden_field :name, value: milestone.name %>
      <!-- Create a checkbox to add the milestone_id to the project -->
      <%= fm.label milestone.name %>
      <%= fm.check_box :milestone_template_id,{}, milestone.id %>
      <br>
      <% milestone.task_templates.each_with_index do |task, another_index| %>
        <%= fm.fields_for :tasks, index: another_index do |ft| %>
          <!-- Create a checkbox for each task in the milestone -->
          <%= ft.label task.name %>
          <%= ft.check_box :task_ids, {}, task.id %>
        <% end %>
      <% end %>
      <br>
    <% end %>
  <% end %>
  <br>
<%= f.submit %>
  <% end %>

提交的内容:

{"utf8"=>"✓", "_method"=>"patch", "authenticity_token"=>"do/NeMW4wvsh8PCOIYAvuDiH0DwKVr6v0Sm55gOuCHM/Fw5h9T0orRjrspcQpNSx5Vp2JOmtVf+3O18P2XB4vA==", "project"=>{"milestones"=>{"0"=>{"name"=>"Yellow Milestone 1", "milestone_template_id"=>"18", "tasks"=>{"0"=>{"task_ids"=>"1"}, "1"=>{"task_ids"=>"0"}, "2"=>{"task_ids"=>"0"}}}, "1"=>{"name"=>"Yellow Milestone 2", "milestone_template_id"=>"0", "tasks"=>{"0"=>{"task_ids"=>"0"}, "1"=>{"task_ids"=>"0"}, "2"=>{"task_ids"=>"0"}}}, "2"=>{"name"=>"Yellow Milestone 3", "milestone_template_id"=>"0", "tasks"=>{"0"=>{"task_ids"=>"0"}, "1"=>{"task_ids"=>"0"}, "2"=>{"task_ids"=>"0"}}}}}, "commit"=>"Update Project", "controller"=>"projects", "action"=>"update", "id"=>"155"}

config/application.rb

require File.expand_path('../boot', __FILE__)

require 'rails/all'

Bundler.require(*Rails.groups)


module Taskit


    class Application < Rails::Application

        config.autoload_paths += %W(#{config.root}/lib)
        config.active_record.raise_in_transactional_callbacks = true
      end


    end

【问题讨论】:

  • 错误信息不是带有源文件名和行号吗?他们通常会...
  • 是的,我在上面的代码中用箭头和注释标记了它。它在 lib/project_updater.rb 中的 Self.perform 下
  • project模型和milestone_template之间是否存在关联关系?冒着明显的风险,params[:project] 是 nil,因此 milestone 信息不会作为嵌套属性传回。
  • 没有。项目有_许多里程碑,里程碑模板有_许多任务模板。项目与里程碑模板无关,除了它是具有多个里程碑模板的模板的子节点.....基本上您创建一个项目并为您提供里程碑模板,为您的项目自动创建里程碑。
  • 如果您从服务器日志中发布了一堆带有错误的行以及我的朋友的问题 :)

标签: ruby-on-rails forms object nested-attributes


【解决方案1】:

首先我认为这行有一个错字:

result = ProjectUpdater.perform(@project, update_params)

我没有看到update_params 方法,所以我认为这应该是project_params。

ProjectUpdater 中的问题是因为params.require(:project) 返回一个没有外部 :project 键的哈希,所以在ProjectUpdater.perform 方法中去掉 :project 键:

milestones = params[:milestones]

【讨论】:

  • 啊,我确实必须将参数添加到 ProjectUpdater.perform(@project, project_params, params) 才能让里程碑= params[:milestones] 工作......但它确实做到了!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-03-04
  • 1970-01-01
  • 1970-01-01
  • 2022-11-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多