Ruby on Rails集成quickbooks-ruby时find、save方法未定义问题求助
1. find/find_by/where方法不存在的原因
Quickbooks::Model::Customer是quickbooks-ruby封装的API数据模型,不是Rails的ActiveRecord模型,自然没有ActiveRecord提供的查询类方法。
另外你原有代码中已经通过companies.each do |company|拿到了单条Network::Company记录,后续写的comp = company.find(i)是完全多余的错误逻辑,直接使用循环变量company即可。
2. save方法不存在的原因
和查询方法同理,save是ActiveRecord模型的实例方法,Quickbooks的模型没有这个方法。quickbooks-ruby的设计是通过Quickbooks::Service::Customer实例提交数据到Quickbooks接口,新增数据调用service.create,更新数据调用service.update。
3. 需要修正的其他逻辑问题
你原代码仅在循环外初始化了一个Quickbooks::Model::Customer实例,循环内反复修改同一个实例,最终只会同步最后一条本地公司数据,每一条本地公司都要对应初始化独立的Customer实例。
如果要避免重复创建客户,需要先拉取Quickbooks端已有的客户列表,做名称匹配后判断是新增还是更新。
另外你原有代码里用&.给嵌套属性赋值的写法有问题,比如primary_phone&.free_form_number,如果primary_phone本身是nil,赋值操作会直接跳过,属性不会被写入,需要先初始化嵌套对象再赋值。
修正后的参考代码
def qb_customers set_client service = Quickbooks::Service::Customer.new service.access_token = @access_token service.company_id = @options[:realm_id] # 先拉取Quickbooks端已有的所有客户,用于去重匹配 qb_existing_customers = service.query(nil, page: 1, per_page: 900000).index_by(&:display_name) local_companies = Network::Company.all local_companies.each do |company| # 匹配已存在的客户,不存在就新建实例 customer = qb_existing_customers[company.name] || Quickbooks::Model::Customer.new # 赋值基础属性 customer.display_name = company.name customer.notes = company.notes # 赋值电话类属性 if company.tel.present? customer.primary_phone = Quickbooks::Model::TelephoneNumber.new unless customer.primary_phone customer.primary_phone.free_form_number = company.tel end if company.gsm.present? customer.mobile_phone = Quickbooks::Model::TelephoneNumber.new unless customer.mobile_phone customer.mobile_phone.free_form_number = company.gsm end if company.fax.present? customer.fax_phone = Quickbooks::Model::TelephoneNumber.new unless customer.fax_phone customer.fax_phone.free_form_number = company.fax end # 赋值邮箱属性 if company.email.present? customer.primary_email_address = Quickbooks::Model::EmailAddress.new unless customer.primary_email_address customer.primary_email_address.address = company.email end # 赋值网站属性 if company.website.present? customer.web_site = Quickbooks::Model::WebSiteAddress.new unless customer.web_site customer.web_site.uri = company.website end # 赋值账单地址属性,注意你原代码里的longitude拼写错误 if company.address.present? || company.city.present? || company.postcode.present? customer.billing_address = Quickbooks::Model::PhysicalAddress.new unless customer.billing_address customer.billing_address.line1 = company.address customer.billing_address.city = company.city customer.billing_address.country = company.state customer.billing_address.postal_code = company.postcode customer.billing_address.country_sub_division_code = company.country_id customer.billing_address.lat = company.latitude customer.billing_address.lon = company.longitude end # 提交数据到Quickbooks if customer.id? # 有id说明是已存在的客户,调用更新 service.update(customer) else # 无id说明是新客户,调用创建 service.create(customer) end end # 返回最新的客户列表 service.query(nil, page: 1, per_page: 900000) end
内容的提问来源于stack exchange,提问作者Kvothe28

