我有一个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操作?
答案 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。