2010-06-01 72 views
0

我想通過創業板使用我們的會計軟件包(FreeAgentCentral)使用API​​發佈一些信息。Rails中的REST API幫助

http://github.com/aaronrussell/freeagent_api/ 

我有下面的代碼得到它的工作(據說):

加瀨控制器

def create 
    @kase = Kase.new(params[:kase]) 
    @company = Company.find(params[:kase][:company_id]) 
    @kase = @company.kases.create!(params[:kase]) 

    respond_to do |format| 
     if @kase.save 
     UserMailer.deliver_makeakase("[email protected]", "Highrise", @kase) 
     @kase.create_freeagent_project(current_user) 

     #flash[:notice] = 'Case was successfully created.' 
     flash[:notice] = fading_flash_message("Case was successfully created & sent to Highrise.", 5) 

     format.html { redirect_to(@kase) } 
     format.xml { render :xml => @kase, :status => :created, :location => @kase } 
     else 
     format.html { render :action => "new" } 
     format.xml { render :xml => @kase.errors, :status => :unprocessable_entity } 
     end 
    end 
    end 

爲了節省您翻翻,重要的部分是:

@kase.create_freeagent_project(current_user) 

加斯模型

# FreeAgent API Project Create 
    # Required attribues 
    # :contact_id 
    # :name 
    # :payment_term_in_days 
    # :billing_basis     # must be 1, 7, 7.5, or 8 
    # :budget_units      # must be Hours, Days, or Monetary 
    # :status       # must be Active or Completed 
    def create_freeagent_project(current_user) 
    p = Freeagent::Project.create(
     :contact_id    => 0, 
     :name     => "#{jobno} - #{highrisesubject}", 
     :payment_terms_in_days => 5, 
     :billing_basis   => 1, 
     :budget_units   => 'Hours', 
     :status     => 'Active' 
    ) 
    user = Freeagent::User.find_by_email(current_user.email) 
    Freeagent::Timeslip.create(
     :project_id => p.id, 
     :user_id => user.id, 
     :hours => 1, 
     :new_task => 'Setup', 
     :dated_on => Time.now 
    ) 
    end 

的lib/freeagent_api.rb

require 'rubygems' 
gem 'activeresource', '< 3.0.0.beta1' 
require 'active_resource' 

module Freeagent 

    class << self 
    def authenticate(options) 
     Base.authenticate(options) 
    end 
    end 

    class Error < StandardError; end 

    class Base < ActiveResource::Base 
    def self.authenticate(options) 
     self.site = "https://#{options[:domain]}" 
     self.user = options[:username] 
     self.password = options[:password] 
    end 
    end 

    # Company 

    class Company 
    def self.invoice_timeline 
     InvoiceTimeline.find :all, :from => '/company/invoice_timeline.xml' 
    end 
    def self.tax_timeline 
     TaxTimeline.find :all, :from => '/company/tax_timeline.xml' 
    end 
    end 
    class InvoiceTimeline < Base 
    self.prefix = '/company/' 
    end 
    class TaxTimeline < Base 
    self.prefix = '/company/' 
    end 

    # Contacts 

    class Contact < Base 
    end 

    # Projects 

    class Project < Base 

    def invoices 
     Invoice.find :all, :from => "/projects/#{id}/invoices.xml" 
    end 

    def timeslips 
     Timeslip.find :all, :from => "/projects/#{id}/timeslips.xml" 
    end 

    end 

    # Tasks - Complete 

    class Task < Base 
    self.prefix = '/projects/:project_id/'   
    end 

    # Invoices - Complete 

    class Invoice < Base 

    def mark_as_draft 
     connection.put("/invoices/#{id}/mark_as_draft.xml", encode, self.class.headers).tap do |response| 
     load_attributes_from_response(response) 
     end 
    end 
    def mark_as_sent 
     connection.put("/invoices/#{id}/mark_as_sent.xml", encode, self.class.headers).tap do |response| 
     load_attributes_from_response(response) 
     end 
    end 
    def mark_as_cancelled 
     connection.put("/invoices/#{id}/mark_as_cancelled.xml", encode, self.class.headers).tap do |response| 
     load_attributes_from_response(response) 
     end 
    end 

    end 

    # Invoice items - Complete 

    class InvoiceItem < Base 
    self.prefix = '/invoices/:invoice_id/' 
    end 

    # Timeslips 

    class Timeslip < Base 

    def self.find(*arguments) 
     scope = arguments.slice!(0) 
     options = arguments.slice!(0) || {} 
     if options[:params] && options[:params][:from] && options[:params][:to] 
     options[:params][:view] = options[:params][:from]+'_'+options[:params][:to] 
     options[:params].delete(:from) 
     options[:params].delete(:to) 
     end 

     case scope 
     when :all then find_every(options) 
     when :first then find_every(options).first 
     when :last then find_every(options).last 
     when :one then find_one(options) 
     else    find_single(scope, options) 
     end 
    end  
    end 

    # Users 

    class User < Base 
    self.prefix = '/company/' 
    def self.find_by_email(email) 
     users = User.find :all 
     users.each do |u| 
     u.email == email ? (return u) : next 
     end 
     raise Error, "No user matches that email!" 
    end 
    end 

end 

配置/初始化/ freeagent.rb

Freeagent.authenticate({ 
    :domain => 'XXXXX.freeagentcentral.com', 
    :username => '[email protected]', 
    :password => 'XXXXXX' 
    }) 

以上試圖創建一個新的渲染時,下面的錯誤案例並將詳細信息發送給FreeAgent:

ActiveResource::ResourceNotFound in KasesController#create 

Failed with 404 Not Found 

ActiveResource::ResourceNotFound (Failed with 404 Not Found): 
    app/models/kase.rb:56:in `create_freeagent_project' 
    app/controllers/kases_controller.rb:96:in `create' 
    app/controllers/kases_controller.rb:93:in `create' 

Rendered rescues/_trace (176.5ms) 
Rendered rescues/_request_and_response (1.1ms) 
Rendering rescues/layout (internal_server_error) 

如果任何人都可以對這個問題有何啓示,將不勝感激!

感謝,

丹尼

回答

1

你是如何調用創建?使用正常的寧靜創建動作,它可以是來自表單或其他東西的POST,但404通常由失敗的GET動作呈現,其中ActiveRecord查找無法找到具有特定ID的記錄。我最好的猜測是,你調用一個GET創建,以及該行

user = Freeagent::User.find_by_email(current_user.email) 

根本無法找到用戶與電子郵件等被拋出ResourceNotFound例外。

此外,這段代碼是混亂的對我說:

@kase = Kase.new(params[:kase]) 
@company = Company.find(params[:kase][:company_id]) 
@kase = @company.kases.create!(params[:kase]) 

respond_to do |format| 
    if @kase.save 

,你爲什麼和kases.create創建@kase這裏兩次,一次與Kase.new和一次?另外,還要注意行:

if @kase.save 

值總是正確的,因爲該行:

@company.kases.create!(params[:kase]) 

會拋出一個異常,如果它是假的,這是說@kase的另一種方式。保存是多餘的,因爲創建!本來可以堅持新的Kase記錄。

編輯:我認爲你的意思做的是:

# this line can go @kase = Kase.new(params[:kase]) 
@company = Company.find(params[:kase][:company_id]) 
@kase = @company.kases.build(params[:kase]) 

編輯:你可能需要一個新的操作是這樣的:

def new 
    @kase = Kase.new # no params here 
end 

「新」僱員再培訓局模板將有一個的form_for類似於:

<% form_for @kase do |k| %> 

等等。該表單將默認地從表單的params傳遞到create action,assum你已經在你的路線中設置了類似資源的東西:kase。這應該讓你開始。按照您所做的標準教程,事情應該變得更簡單。

+0

我有雙重/三重檢查,當前用戶的電子郵件地址與免費電子郵件地址相匹配。 ResourceNotFound異常會有其他原因嗎? 我需要看看你的第二個評論關於kase創建,我認爲你的權利! 謝謝, 丹尼 – dannymcc 2010-06-01 16:58:57

+0

這是我可以看到可能會拋出ResourceNotFound的唯一線。可能是一些空格fu導致失敗的發現?在find_by_email之後添加一些輸出,以確保找到用戶。 然後查看服務器輸出進行驗證。 – 2010-06-01 17:04:56

+0

會做。謝謝! – dannymcc 2010-06-01 17:06:28