首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Rails - NoMethodError

Rails - NoMethodError
EN

Stack Overflow用户
提问于 2013-05-22 18:38:39
回答 2查看 900关注 0票数 3

当我的NoMethodErrors运行时,我正在接收DeltaSynWorker。这种情况发生在作为当前工作应用程序的修订版构建的应用程序中。我不是最初的程序员,我是从Java背景中来的(我提到这一点是因为我可能遗漏了一些对其他人来说很明显的东西)。当代码与当前在不同的web应用程序中运行良好的代码非常相似时,我不知道为什么会抛出NoMethodeError

错误:

代码语言:javascript
复制
NoMethodError: undefined method `client' for #<ApiRequestBuilder:0x0000000705a8f0>

delta_sync_worker.rb

代码语言:javascript
复制
class DeltaSyncWorker < SyncWorker

  include Sidekiq::Worker
  sidekiq_options queue: "delta_syncs"

  def perform(subscriber_id, client_id)

      sleep(10)
      current_subscriber = ApiSubscriberDecorator.decorate(Subscriber.find(subscriber_id))
      Time.zone = current_subscriber.time_zone
      client = ApiClientDecorator.decorate(Client.find(client_id))
      arb = ApiRequestBuilder.new(URI.parse(SR_HOST + '/servlet/sync/process'))

      if arb.client(:subscriber => current_subscriber, :client => client)

        arb.transmit

        if arb.success?
          current_subscriber.touch(:sync_updated_at)
          decorated_client = ClientDecorator.decorate(client.model)        
          ConfirmationsSyncWorker.perform_in(1.hours, current_subscriber.id)
        else
          error_params = {:subscriber => current_subscriber.id, :response_body =>            arb.response.body, :request_body => arb.request.body, :sync_type => "DeltaSyncWorker"}
          Airbrake.notify(:error_class => "sync_error", :error_message => "Sync Error: #{arb.response.message}", :params => error_params)
        end
      end
    end
  end

api_request_builder.rb

代码语言:javascript
复制
require 'nokogiri'
class ApiRequestBuilder < AbstractController::Base
  include AbstractController::Rendering
  include AbstractController::Layouts
  include AbstractController::Helpers
  include AbstractController::Translation
  include AbstractController::AssetPaths

  self.view_paths = "app/api"

  attr_accessor :request_body, :request, :response, :append_request_headers, :request_method, :url

  def initialize(url, *args)
    @url = url
    if args
      args.each do |arg|
        arg.each_pair{ |k,v| instance_variable_set("@#{k.to_s}", v) }
      end
    end
  end

  # this will search for an api request template in api/requests, render that template and set any instance variables
  def method_missing(meth, *args, &block)

    if lookup_context.template_exists?("requests/#{meth.to_s}")

      if args
        args.each do |arg|
          arg.each_pair{|k,v| instance_variable_set("@#{k.to_s}", v) }
        end
      end

      @request_body = (render :template => "requests/#{meth.to_s}")
    else
      super
    end

  end

  def transmit
    @request_method ||= "Post"
    @request = "Net::HTTP::#{@request_method}".constantize.new(@url.path)
    @request['x-ss-user'] = @subscriber.sr_user if @subscriber &&        @subscriber.sr_user.present?
    @request['x-ss-pwd'] =  @subscriber.sr_password if @subscriber && @subscriber.sr_password.present?

    unless @append_request_headers.nil?
      @append_request_headers.each_pair{ |k,v| @request[k] = v }
    end
    @request.body = @request_body if request_body? && @request.request_body_permitted?

    @http = Net::HTTP.new(@url.host, @url.port)
    @http.use_ssl = true
    @http.verify_mode = OpenSSL::SSL::VERIFY_NONE
    @response = @http.request(@request)

  end

  def success?
    if @response.code == 200.to_s
      return true
    else
      return false
    end
  end

  def request_body?
    unless @request_body.nil?
      return true
    else
      return false
    end
  end
end

我一直在看其他的NoMethodError问题,但我找不到一个答案,我觉得适用于我的情况。任何帮助都是非常感谢的。谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-05-22 18:56:57

method_missing将捕获未定义方法的发送消息,最后对super的调用将传递给Ruby的标准method_missing行为,这就是您正在看到的(NoMethodError)。但是,只有在不满足if条件的情况下才会发生这种情况,这就是我在这里所怀疑的情况,并解释了为什么它在某些情况下工作,而在其他情况下则不工作。对:client的调用在继承链上没有找到匹配的方法,它将查找一个名为“Request/client”的模板--尝试添加该模板,并查看是否解决了这个问题。

票数 1
EN

Stack Overflow用户

发布于 2013-05-23 04:26:44

我知道我以前见过这种情况,而且我觉得它并不像看上去的那样,但基本上,您缺少的方法只是拦截方法调用,当您调用arb.client时,它会被方法缺失所捕获,因此尝试呈现api/client.xml.arb或api,不管文件类型是什么。--请注意,初始化器目录中应该有一个名为api_template_handler.rb或arb_temmplate_handler.rb之类的文件,它允许rails在视图目录中看到模板类型--确保这是第一个。另外,_client.xml.api是该目录中的另一个api请求使用的一个部分(完全同步),

要调试Id,请从下面的行开始

代码语言:javascript
复制
if lookup_context.template_exists?("requests/#{meth.to_s}")

添加日志语句

代码语言:javascript
复制
Rails.logger.debug "Can I see View?" + lookup_context.template_exists?("requests/#{meth.to_s}")

如果是的话,那么问题是,由于缺少方法,错误没有被正确捕获。如果为false,则sidekiq工作者没有正确加载rails,或者视图路径没有被添加到rails视图路径中。

如果是这样的话,我猜这可能与构建器试图调用的客户端模型没有加载,或者客户端模型上不存在的属性有关,并且错误正以某种方式出现在api请求生成器类中。

哦,也只是一般的东西,但是要确保redis和sidekiq都在运行,如果不是本地环境的话,重新启动乘客。

告诉我事情进展如何。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16699273

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档