2009-05-20 6 views
15

J'ai une application Rails qui a une ressource d'entreprise avec un employé nested resource. J'utilise le routage peu profonde, afin de manipuler les employés, mes itinéraires sont:Comment utiliser ActiveResource avec des itinéraires imbriqués peu profonds?

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

Comment puis-je créer, lire, mettre à jour et détruire les employés utilisant ActiveResource?

Pour créer des employés, je peux utiliser:

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

Mais si j'essaie de faire:

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

-je obtenir un 404 parce que la route/entreprises /: company_id/employés /: id n'est pas défini lorsque des itinéraires peu profonds sont utilisés.

Pour lire, modifier et supprimer des employés, je peux utiliser:

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

Mais il ne semble pas être un moyen de créer de nouveaux employés, en raison de l'absence des sociétés de route extérieure.

Une solution consisterait à définir des classes CompanyEmployee et Employee séparées, mais cela semble trop complexe. Comment puis-je utiliser une seule classe Employee dans ActiveResource pour effectuer les quatre opérations CRUD?

Répondre

10

Il existe une méthode d'instance protégée nommée collection_path que vous pouvez remplacer.

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 

Vous seriez alors capable de créer des employés.

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

Il ne semble pas que les prefix_options est documentée autrement que dans la méthode clone alors cela pourrait changer dans les prochaines versions.

+0

travaillé très bien, sauf que je devais utiliser «/entreprises/# {prefix_options [: company_id]} /#{self.class.collection_name},xml "ou le POST n'a pas été interprété comme XML. –

+4

doit utiliser 'self.prefix ="/companies /: company_id/"' au lieu de surcharger 'collection_path' – tybro0103

14

J'utilise Rails 3.0.9. Vous pouvez définir le préfixe comme ceci:

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

Et puis

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

ou

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

Il remplacera: company_id par la valeur de prefix_options.

0

Voir cet article: http://blog.flame.org/2009/11/04/activeresource-and-shallow-nested-routes.html

Ici, l'auteur propose de remplacer la méthode de classe collection_path. Cela a du sens puisque cette méthode est également utilisée par new_element_path et récupérera le même chemin dans les deux cas.

Exemple:

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 

Ensuite, vous pouvez trouver des employés pour une entreprise en faisant:

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