Как использовать ActiveResource с мелкими вложенными маршрутами?
У меня есть приложение Rails, у которого есть ресурс компании с вложенным ресурсом 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, потому что маршрут/компании/: company_id/employees/: id не определен, когда используются мелкие маршруты.
Чтобы читать, редактировать и удалять сотрудников, я могу использовать:
class Employee < ActiveResource::Base
self.site = "http://example.com"
end
Но тогда, похоже, не существует способа создать новых сотрудников из-за отсутствия внешних маршрутов компаний.
Одним из решений было бы определить отдельные классы CompanyEmployee и Employee, но это кажется слишком сложным.
Как я могу использовать один класс Employee в ActiveResource для выполнения всех четырех операций CRUD?
Ответы
Ответ 1
Существует защищенный метод экземпляра с именем 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 документируется иначе, чем в методе clone, поэтому это может измениться в будущих выпусках.
Ответ 2
Я использую 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
Он заменит: company_id значением из prefix_options.
Ответ 3
Смотрите эту статью: 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 })