Как использовать ActiveResource с неглубокими вложенными маршрутами? - PullRequest
15 голосов
/ 20 мая 2009

У меня есть приложение Rails, у которого есть ресурс Company с вложенным ресурсом Сотрудник. Я использую мелкую маршрутизацию, поэтому, чтобы манипулировать сотрудником, мои маршруты:

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 / employee /: id не определяется при использовании мелких маршрутов.

Чтобы читать, редактировать и удалять сотрудников, я могу использовать:

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

Но тогда, похоже, нет способа создать новых сотрудников из-за отсутствия внешнего маршрута компаний.

Одним из решений было бы определение отдельных классов CompanyEmployee и Employee, но это кажется слишком сложным.

Как я могу использовать один класс Employee в ActiveResource для выполнения всех четырех операций CRUD?

Ответы [ 4 ]

14 голосов
/ 27 июля 2011

Я использую 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.

10 голосов
/ 22 мая 2009

Существует защищенный метод экземпляра с именем 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, поэтому это может измениться в будущих выпусках.

0 голосов
/ 24 октября 2018

Я нашел, что лучше переопределить 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, как предлагается в других решениях.

0 голосов
/ 10 августа 2012

См. Эту статью: 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 })
...