16

我有一个 Rails 应用程序,它有一个 Company 资源和一个嵌套资源Employee。我正在使用浅层路由,因此要操作 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 是因为使用浅层路由时未定义路由 /companies/:company_id/employees/:id 。

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

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

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

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

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

4

4 回答 4

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。

于 2011-07-26T20:39:15.947 回答
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

除了 clone 方法之外,似乎没有记录 prefix_options ,因此这可能会在未来的版本中发生变化。

于 2009-05-22T02:27:42.697 回答
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 })
于 2012-08-10T15:06:29.317 回答
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 分配给实例。

于 2018-10-24T18:14:19.737 回答