如何使用浅嵌套路由的ActiveResource?

时间:2009-05-20 18:51:48

标签: rest activeresource

我有一个Rails应用程序,其公司资源包含nested resource员工。我正在使用浅层路由,所以为了操纵Employee,我的路由是:

GET     /employees/1
PUT     /employees/1
DELETE  /employees/1
POST    /companies/1/employees

如何使用ActiveResource创建,读取,更新和销毁员工?

要创建员工,我可以使用:

class Employee < ActiveResource::Base
  self.site = "http://example.com/companies/:company_id"
end

但如果我尝试这样做:

e=Employee.find(1, :params => {:company_id => 1})

我得到404,因为在使用浅路线时未定义route / companies /:company_id / employees /:id。

要阅读,编辑和删除员工,我可以使用:

class Employee < ActiveResource::Base
  self.site = "http://example.com"
end

但由于缺乏公司外部路线,似乎没有办法创建新的员工。

一种解决方案是定义单独的CompanyEmployee和Employee类,但这似乎过于复杂。

如何在ActiveResource中使用单个Employee类来执行所有四个CRUD操作?

4 个答案:

答案 0 :(得分:14)

我正在使用Rails 3.0.9。您可以像这样设置前缀:

class Employee < ActiveResource::Base
  self.prefix = "/companies/:company_id/"
end

然后

Employee.find(:all, :params => {:company_id => 99})

e = Employee.new(:name => "Corey")
e.prefix_options[:company_id] = 1

它将使用prefix_options中的值替换:company_id。

答案 1 :(得分:10)

您可以覆盖一个名为collection_path的受保护实例方法。

class Employee < ActiveResource::Base
  self.site = "http://example.com"

  def collection_path(options = nil)
    "/companies/#{prefix_options[:company_id]}/#{self.class.collection_name}"
  end
end

然后,您就可以创建员工。

e = Employee.new(:name => "Corey")
e.prefix_options[:company_id] = 1
e.save

除了克隆方法之外,似乎没有记录prefix_options,因此在将来的版本中可能会更改。

答案 2 :(得分:0)

请参阅此文章:http://blog.flame.org/2009/11/04/activeresource-and-shallow-nested-routes.html

这里,作者建议覆盖类方法collection_path。这是有道理的,因为new_element_path也使用了这个方法,并且在两种情况下都会检索相同的路径。

示例:

class Employee < ActiveResource::Base
  self.site = "http://example.com"

  def self.collection_path(prefix_options = {},query_options=nil)
    super
    "/companies/#{query_options[:company_id]}/#{collection_name}.#{format.extension}#{query_string(query_options)}"
  end
end

然后,您可以通过以下方式找到公司的员工:

company = Company.find(:first)
Employee.find(:all, :params => {:company_id => company.id })

答案 3 :(得分:0)

我发现最好用与库中定义的功能相同的功能覆盖ActiveResource::Base.element_path,但在返回值中省略prefix_options的使用。没有

class Employee < ActiveResource::Base
  self.site = 'http://example.com'
  self.prefix = '/companies/:company_id/'

  # Over-ride method and omit `#{prefix(prefix_options)}` from the returned string
  def self.element_path(id, prefix_options = {}, query_options = nil)
    "/#{collection_name}/#{URI.parser.escape id.to_s}.#{format.extension}"
  end
end

然后,Employee类将照常运行,而无需按照其他解决方案中的建议为实例分配prefix_options。