2010-06-01 71 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