2014-08-28 59 views
0

编辑:事实证明我犯了一个非常简单的错误,并且有一个与LocalTemplate ID不再存在关联的模板。如果任何人有这个问题,并认为他们以某种方式无法将他们的更新操作中的其他模型的id关联,请确保您没有意外删除导致该ID不再存在的父对象! 下面的代码虽然大大简化,但对我来说却很有用。Rails NoMethodError未定义的方法'数据'为零:NilClass(控制器#更新)

我在我的Rails应用程序中有模板模型。它有一个在其中定义的“数据”方法。

我可以通过@ template.data在创建和显示操作中访问此方法,但是当在我的控制器的更新操作中使用相同的@ template.data时,我得到一个无方法错误,因为我没有显示正确的本地模板ID。这条线可以在它读取的模型中找到base_data = YAML.load(local_template.data)

当初始保存新模板时,我存储了一个关联的local_template的id,但是如何确保我在更新操作中再次引用该id,所以我不得到一个没有方法的错误?

这里是模板模型和控制器的简化版本

型号:

class Template < ActiveRecord::Base 
     def data 
     base_data = YAML.load(local_template.data) 
     # couldn't pass the correct LocalTemplate here because 
     # the local_template_id I had in my Template model no 
     # longer existed. Changing the id to a LocalTemplate 
     # that did exist fixed the issue. 
     end 
    end 

控制器:

class TemplatesController < ApplicationController 
     def index 
     @business = Business.find(params[:business_id]) 
     @templates = @business.templates.all 
     end 

     def new 
     @business = Business.find(params[:business_id]) 
     @local_templates = LocalTemplate.all 
     @template = @business.templates.build 
     end 

     def create 
     @business = Business.find(params[:business_id]) 
     @local_templates = LocalTemplate.all 
     @template = @business.templates.build(template_params) 

     if @template.save 
      @template.data #works fine here 

      redirect_to business_url(@template.business_id) 
     else 
      render 'new' 
     end 
     end 

     def show 
     @business = Business.find(params[:business_id]) 
     @template = @business.templates.find(params[:id]) 
     @template.data #works fine here too 
     end 

     def edit 
     @business = Business.find(params[:business_id]) 
     @local_templates = LocalTemplate.all 
     @template = @business.templates.find(params[:id]) 
     end 

     def update 
     @business = Business.find(params[:business_id]) 
     @template = @business.templates.find(params[:id]) 

     if @template.update_attributes!(pass_template_params) 

      Api.new.update_template(@template.data.to_json) #this is where I had a problem 

      redirect_to business_url(@template.business_id) 
     else 
      render 'edit' 
     end 
     end 
    end 
+0

我真的有麻烦协调'@ template.update_attributes(template_params)'与'@template.data#不能在这里使用它或我得到一个没有方法错误'你是否覆盖'update_attributes' in 'Template'? – 2014-08-28 04:18:51

+0

为了让事情清楚,我删除了很多代码,但在'if @ template.update_attributes(template_params)'之后,我做了一个需要使用@ template.data的API调用。我没有显示电话,但这是它的去向,它不起作用。 – dual88 2014-08-28 04:21:41

+0

之后,该行类似于:'Api.new.update_template(@ template.data)' – dual88 2014-08-28 04:24:26

回答

0

您正在混合很多。在您的控制器中需要重构很多...
首先,您的TemplatesController应该是关于模板资源的,但您的控制器看起来更像是一个BusinessesController。一般来说,例如您的更新操作应该更像:

def update 
    @template = Template.find params[:id] 
    @template.attributes = template_params # though this should raise a NoMethodError, because you dind't define it; I'd prefer params[:template] if possible 
    if @template.save 
    redirect_to business_url(@template.business_id) 
    else 
    @local_templates = LocalTemplate.all 
    render 'edit' 
    end 
end 

实例化@business和@local_templates使得非有道理的,因为你不使用它。如果可以的话,加快你的反应! :)
修复了在更新中不需要嵌套资源的开销(就像您这样做)。

@template.business 

在/templates/edit.html.erb部分:
如果在保存@Template无法进行验证的原因,你应该更好地通过后期加载的业务对象。然后,你也不需要一个嵌套的路径来编辑你的行为......你看,它清理了很多。
作为一般指导,您应尽可能少地创建控制器实例变量。
如果清理了控制器和视图,调试数据问题将更容易。
我认为:

local_template 

在你的模板模型是有联系LocalTemplate模型对象。所以应该没有问题,打电话,如果你的任何地方确保引用的对象存在:

class Template < ActiveRecord::Base 
    def data 
    return if local_template.nil? 
    YAML.load(local_template.data) 
    end 
end 

或验证local_template对象的存在。或甚至b

+0

感谢@tobago我的代码示例被大大简化,只显示我认为与问题直接相关的内容。在实际的控制器中会有更多的复杂性。模板属于企业,并从特定的企业视图进行编辑。您是对的,但我犯了一个简单的错误,那就是属于LocalTemplate的Template不再存在。我不得不给它一个新的LocalTemplate ID,然后我的更新操作工作。谢谢! – dual88 2014-08-28 17:54:29

0

你应该确认@Template不为零,如果@Template是无,你不能使用数据方法。

1.9.3-p547 :024 > nil.data 
NoMethodError: undefined method `data' for nil:NilClass 
from (irb):24 
from /Users/tap4fun/.rvm/rubies/ruby-1.9.3-p547/bin/irb:12:in `<main>' 

而且您应该使用update_attributes!,如果记录无效,可以引发异常。

你可以这样做。

if @template 
    @template.update_attributes!(template_params) 
    @template.data 
end 
+0

谢谢,我发现问题实际上在模型'base_data = YAML.load(local_template.data)'这一行中,并更新了我的问题。我仍然不确定确切的解决方案。我将使用update_attributes!虽然;感谢您指出了这一点。 – dual88 2014-08-28 04:44:51

相关问题