2016-06-21 14 views
0

Ich habe Railscasts bei der Implementierung von Paypal Standardzahlungen verfolgt. Beim Empfangen von IPN-Benachrichtigungen erkannte ich, dass ich keine Artikelspezifikationen wie item_name, item_number, & quantity erhielt. Nach einigen Untersuchungen, ich dachte, ich sich in meinem Controller falsch geschrieben hatte, als PayPal die Variablen als item_name1 sendet, item_number1, quantity1, item_name2, item_number2, quantity2 und so weiterPayPal IPN - Paypal Website Standard

Ich habe den Railscasts Setup bekommt. Die Meldungen kommen über einen Controller

PaymentNotificationsController < ApplicationController 
    protect_from_forgery except: [:create] 
    def create 
     PaymentNotification.create!(params: params, 
     item_number: params[:item_number], item_name: params[:item_name], quantity: params[:quantity] 
     render nothing: true 
    end 

In einem Fall, in dem ein Auftrag mehrere Elemente hat, wäre es item_name1, item_name2, item_name3 und so weiter sein. Was ist der richtige Weg, um diese Variablen zu benennen, um die paypal IPN-Benachrichtigungen akzeptieren zu können, ohne für jedes zusätzliche Element eine Spalte hinzuzufügen?

Vielen Dank im Voraus!

+0

Sie können die 'params' vor dem Aufruf von' PaymentNotification.create! 'Betrachten. Mache 'params.include? (: Item_name1)', um zu prüfen, ob es einen solchen Schlüssel gibt, und wenn ja, überprüfe, wie viele Items vorhanden sind, indem du die Parameter 'item_name2',' item_name3' usw. durchsuchst, bis du a findest fehlender Param. –

+0

@ RoryO'Kane Wenn es Ihnen nichts ausmacht, können Sie ein Beispiel als Antwort schreiben? –

Antwort

0

Sie können die params vor dem Aufruf PaymentNotification.create! betrachten. Mit einer Schleife, um zu überprüfen, welche Felder innerhalb params sind, können Sie zählen, wie viele Elemente vorhanden sind, und alle ihre Eigenschaften in ein Array extrahieren. Danach können Sie die Daten in diesem Array wie gewünscht verwenden.

Dieser Code setzt voraus, dass PayPal nie eine Antwort mit einem Feld item_name sendet - dass, wenn es ein Element gibt, sie noch ein Feld item_name1 senden. Ich weiß nicht, ob das tatsächlich stimmt.

ITEM_PARAM_PREFIXES = ["item_name", "item_number", "quantity"] 

def extract_ipn_items_params(params) 
    item_params = [] 

    loop do 
    item_num_to_test = item_params.length + 1 
    item_num_suffix = item_num_to_test.to_s 
    possible_param_name = ITEM_PARAM_PREFIXES[0] + item_num_suffix 
    if params.include?(possible_param_name) 
     this_item_params = {} 
     ITEM_PARAM_PREFIXES.each do |prefix| 
     this_item_params[prefix] = params[prefix + item_num_suffix] 
     end 
     item_params.push this_item_params 
    else 
     return item_params 
    end 
    end 
end 

Da einige params wie

{"item_name1"=>"cards", "item_number1"=>"123", "quantity1"=>"1", 
"item_name2"=>"book", "item_number2"=>"55", "quantity2"=>"2", 
"other_fields"=>"whatever"} 

Das obige Verfahren sollte dieses Array von Hashes zurück:

[{"item_name"=>"cards", "item_number"=>"123", "quantity"=>"1"}, 
{"item_name"=>"book", "item_number"=>"55", "quantity"=>"2"}] 

Hoffentlich Format, das Sie auf einfache Weise zu tun, was Sie mit diesen Informationen müssen . Sie können beispielsweise .length aufrufen, um zu zählen, wie viele Elemente vorhanden sind, und Sie können über jedes Element iterieren und jeden Hash an PaymentNotification.create! übergeben, wenn Sie für jedes Element eine separate Benachrichtigung wünschen.

+0

Ich habe eine 'before_action: extract_ipn_items_params, nur: [: create]' verwendet, um sie auszulösen, aber ich habe 'ArgumentError (falsche Anzahl von Argumenten (0 für 1)): app/controllers/payment_notifications_controller.rb: 7: in' extract_ipn_items_params '' –

+0

@Rails_learner Der Fehler bedeutet, dass die Funktion mit null Argumenten aufgerufen wird, obwohl sie ein Argument (' params') erwartet. Sie erhalten es, weil die Funktion, die ich Ihnen gab, so konzipiert ist, manuell von einem Controller aufgerufen zu werden und den 'params'-Hash zu übergeben, nicht als' before_action' des Modells bezeichnet, wo es keine 'params' gibt. Ich weiß nicht genug über Ihre App, um tatsächlich Ihre Controller-Aktion zu schreiben, aber ich nehme an, Sie möchten 'items_params = extract_ipn_items_params (params)' schreiben und dann eine Verarbeitung mit dem Ergebnis durchführen, wie ich es im letzten Absatz meiner Antwort vorgeschlagen habe. –

+0

So sieht mein Controller nun aus, wie kann ich die Funktion manuell auslösen? >> [https://www.dropbox.com/s/2f508296wb378wc/sublime.png?dl=0](https://www.dropbox.com/s/2f508296wb378wc/sublime.png? dl = 0) –