2015-08-10 3 views
0

J'utilise le raisin pour le développement de mon api de rails qui fonctionne très bien pour tout le modèle sauf la forme de modèle dynamique. Nous avons des modèles suivants ..Comment créer des routes API dynamiques avec Grape on Rails et valider des paramètres personnalisés

1- product_type 
2- product_fields 
3- products 

Le product_type est HAVING association has_many à la fois modèle et product_fieldsproducts. Lors de la création d'un nouveau product_type, nous pouvons créer divers attributs de champ pour ce product. Chaque product a des attributs différents, mais nous les stockons dans des "produits". Je veux générer l'API dynamiquement chaque fois que product_type est ajouté.

J'ai essayé comme indiqué ci-dessous mais continue à recevoir des erreurs lors de la publication de l'enregistrement. Appréciez toute suggestion.

require 'grape' 

module API 
    module V1 
     class Products < Grape::API 
      include API::V1::Defaults    
      @product_type=ProductType.all 
      @product_type.each do |producttype| 
       resource :"#{producttype.name}" do 
        desc "Create a new product for #{producttype.name}" 
        params do 
         requires :product_type_id , type: "Integer", desc: "product type Id" 
         producttype.productfields.each do |field| 
          if field.is_required? 
           requires :"#{field.field_name}" , type: "#{field.filed_type}", desc: "#{field.field_name}" 
          else 
           optional :"#{field.field_name}", type: "#{field.filed_type}", desc: "#{field.field_name}" 
          end 
         end 
        end 
        post do 
         Products.create!({ 
          product_type_id:params[:product_type_id], 
          ........ 
          ........ 
          ........ 
         }) 
        end 
       end 
      end 
     end 
    end 
end 

Erreur:

NoMethodError - undefined method `collect' for nil:NilClass: 
    grape-swagger (0.10.1) lib/grape-swagger.rb:70:in `block in combine_namespace_routes' 
    grape-swagger (0.10.1) lib/grape-swagger.rb:65:in `combine_namespace_routes' 
    grape-swagger (0.10.1) lib/grape-swagger.rb:39:in `add_swagger_documentation' 
    app/controllers/api/v1/base.rb:10:in `<class:Base>' 
    app/controllers/api/v1/base.rb:6:in `<module:V1>' 
    app/controllers/api/v1/base.rb:5:in `<module:API>' 
    app/controllers/api/v1/base.rb:4:in `<top (required)>' 
+0

Pourriez-vous 1) s'il vous plaît élaborer votre question et l'enrichir avec un exemple et à quoi vous voulez que les URL API ressemblent et 2) assurez-vous que la documentation de vigne ne couvre pas ce problème – croeck

+0

, J'ai mis à jour ma question. – Sri

Répondre

0

D'accord, thx pour mettre à jour votre question, maintenant on peut voir le problème. Pour autant que je comprenne, ce que vous avez l'intention de faire est de créer un itinéraire API pour chaque type de produit. Cependant, votre approche ne fonctionnera pas comme prévu. Grape génère les routes API uniquement pendant la phase d'initialisation de l'application et non lors de l'exécution.

Qu'est-ce que vous avez à faire à la place est de définir votre itinéraire comme suit:

params do 
    requires :producttype_id, type: Integer, desc: "The product type's ID" 
end 
post '/:producttype_id' do 
    # check if params[:producttype_id] is valid, otherwise raise 404 
    ProductType.find([params[:producttype_id]]) 

    # raise an error if the ProductType was not found 
    error! 'ProductType not found', 404 

    # do some stuff... 

    # return your response 
    { producttype_id: params[:producttype_id] } 
end 

Il doit y avoir qu'une seule voie de l'API pour les ProductTypes pour couvrir toutes les instances d'objets actuels et futurs. Cependant, vous devez ensuite valider l'existence de l'instance!

Cela résout votre problème pour créer les routes API dynamiques, mais ne couvre pas la validation des paramètres selon que le champ ProductType est requis ou non. Personnellement, je voudrais intégrer cette logique de validation dans le code, plutôt que la route elle-même. Néanmoins, vous pouvez également écrire votre validateur personnalisé qui charge l'instance ProductType, puis valide les paramètres restants. J'ai récemment décrit cette approche dans How to validate this hash parameter?