【问题标题】:Undefined Method error 'find(), find_by(), find_by_id(), where()' Ruby on Rails未定义的方法错误'find()、find_by()、find_by_id()、where()' Ruby on Rails
【发布时间】:2021-08-11 09:21:41
【问题描述】:

我是 Ruby on Rails 的新手,我正在尝试将属性从一个模型分配给另一个模型。更具体地说,我正在尝试将我的 Ruby on Rails 应用程序与 Quickbooks Online 集成(使用 Ruckus 的quickbooks-ruby gem)。但是我不能将我的公司(客户)分配给 quickbooks 客户模型。我正在使用Ruby 2.7.2p137Rails 6.0.3 OAuth 过程已完成并且工作正常。

我收到Undefined method error 'find' for #<Quickbooks::Model::Customer:0x00007ff178b0ebd8> 错误。我 %100 确定我做错了什么,但我不知道在哪里。我尝试使用此代码为 quickbooks 模型分配属性(顺便说一句,在服务类下运行);

    def qb_customers
      set_client #For setting the OAuth client works fine.
      service              = Quickbooks::Service::Customer.new
      service.access_token = @access_token 
      service.company_id   = @options[:realm_id] 
      companies            = Network::Company.all
      customer             = Quickbooks::Model::Customer.new
      i = 0
      companies.each do |company|
        comp = company.find(i)
        if comp.name == customer.display_name
          i += 1
        else
          customer.display_name                               = comp.name
          customer.primary_phone&.free_form_number            = comp.tel
          customer.mobile_phone&.free_form_number             = comp.gsm
          customer.fax_phone&.free_form_number                = comp.fax
          customer.primary_email_address&.address             = comp.email
          customer.web_site&.uri                              = comp.website
          customer.billing_address&.line1                     = comp.address
          customer.billing_address&.city                      = comp.city
          customer.billing_address&.country                   = comp.state
          customer.billing_address&.postal_code               = comp.postcode
          customer.billing_address&.country_sub_division_code = comp.country_id
          customer.billing_address&.lat                       = comp.latitude
          customer.billing_address&.lon                       = comp.longtude
          customer.notes                                      = comp.notes
          customer.save
        end
      end
      customers = service.query(nil, :page => 1, :per_page => 900000)
    end

find_by()find_by_id()where() 也试过这个块,但它们都返回了未定义的方法错误。

所以我尝试了不同的方法;

companies.each do |comp|
      if comp.name != customer.display_name
        customer.display_name                               = comp.name
        customer.primary_phone&.free_form_number            = comp.tel
        #same attributes here
        .
        .
        .
        customer.notes                                      = comp.notes
        customer.save
      else 
        next
      end
    end

这次我收到了undefined method 'save' for #<Quickbooks::Model::Customer:0x00007ff178b0ebd8> 错误。所以我真的被困在这里我不确定到底出了什么问题。感谢您的宝贵时间。

【问题讨论】:

  • 这个问题有些可疑。 "Undefined method error 'find' for #<:model::customer:0x00007ff178b0ebd8>" 建议您在 Quickbooks::Model::Customer 实例上调用 find,但在在Network::Company.all 结果(companies)上调用问题(第一个代码块),我假设它返回 ActiveRecord 关系,而不是Quickbooks::Model::Customer 实例。
  • 我按原样再次运行它,它给出了undefined method 'find' for #&lt;Network::Company:0x00007fdbf973d6b0&gt; 糟糕,我记得,我用“保存”复制了底部错误,然后将其更改为查找。我认为这不会是一个问题,因为两者都是未定义的方法错误,但是是的,我对此不小心抱歉。
  • 另外,您在迭代之外实例化新的Quickbooks::Model::Customer...这只会用下一个覆盖客户的先前数据...
  • 什么是Network::Company?你自己定义的吗?它是由其他宝石定义的吗?看起来它不是 ActiveRecord 模型,因为在您之前的评论中您说 Network::Company.all 返回 #&lt;Network::Company:0x00007fdbf973d6b0&gt; 而 Rails 模型将返回 ActiveRecord 关系。
  • 第二个代码块的错误比较明显。 Quickbooks::Model::Customer 实例没有 save 方法(它不是 Rails 模型实例)。 GitHub 上的自述文件说您应该使用 service.update(customer) 更新您的对象。

标签: ruby-on-rails ruby quickbooks-online


【解决方案1】:

第二个代码块中的错误是因为 customerQuickbooks::Model::Customer 实例。您当前将其视为 ActiveRecord 模型实例,但事实并非如此。当我们查看documentation for this class 时,您会发现那里没有save 方法。

GitHub readme 为我们提供您正在寻找的信息:

更新对象

默认情况下,更新一个对象将取消设置任何不是的属性 在更新请求中指定。也就是说,更新不是稀疏的 默认。因此,请小心,因为您可能会意外取消设置属性 你没有指定。

例子:

# fetch a Customer to change their name
customer = service.fetch_by_id("99")
customer.company_name = "Neo Pets"
service.update(customer)

在上面的示例中,因为我们检索了所有字段,然后只 更改了单个属性,我们已将“完整”实体返回 到 Intuit,实际上只更改了名称。

如果您手头没有完整的对象并且只想更改 几个属性,而无需取消设置您未指定的内容 比你想使用稀疏更新:

# update a Customer's name when we only know their ID
customer = Quickbooks::Model::Customer.new
customer.id = 99
customer.company_name = "New Company Name"
service.update(customer, :sparse => true)

所以你应该使用service.update(customer) 而不是customer.save 来更新数据。


由于您没有提供有关 Network::Company 类的任何信息,并且它不是“quickbooks-ruby” gem 的一部分,所以我无法帮助您处理第一个代码块。如果您希望解决该问题,则必须提供更多详细信息。

【讨论】:

    【解决方案2】:

    我可以推荐阅读https://dev.to/adamlombard/ruby-class-methods-vs-instance-methods-4aje

    基本上 find_by() find_by_id() where() 是类方法。您正在尝试在该类的实例上调用它们:comp = company.find(i)

    在不了解 quickbook 的情况下,我确定这条线需要看起来像这样

    Network::Company.find(i)
    

    还值得一提的是,您已经使用companies = Network::Company.all 检索了所有Network::Companys,并且当您遍历它们时,信息已经可用,您无需再次检索它们。

    【讨论】:

    • 感谢您的回答。那么我具体应该怎么做呢?我应该使用什么样的结构来分配这些属性。我尝试用Network::Company.find(i) 替换,但这次我得到undefined method 'each' 错误。
    • 我猜这是一个完全不同的问题和问题。我可以建议实际尝试将您的代码减少到实际问题并尝试解决这个问题。 Stackoverflow 不太适合调试多个问题和调试帮助。
    • 这不是“调试”或“多个问题”,我只是按照您的建议,发现它不起作用。问题是一样的,当我以某种方式绕过由find() 方法引起的错误时,我得到一个不同的错误,例如undefined method 'save' 所以显然这里发生了一些不同的事情。
    • 好吧。 undefined method 'each' 来自哪里?
    • 我猜来自each do 迭代。
    【解决方案3】:

    正如我们can see here,gem 中的“模型”不是ApplicationRecord,所以它没有实现像findwheresave 这样的ActiveRecord 方法。

    Customer 模型本身is a parser of XML

    如果你想操作数据库操作,我建议你创建自己的Customer模型,并从quickbooksgem返回的这个对象构建。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-05
      • 1970-01-01
      • 2022-11-19
      相关资源
      最近更新 更多