2011-10-07 3 views
1

J'ai une table d'importation générique qui permet le chargement de fichiers CSV dans différentes colonnes de ma table d'importation. La même table d'importation est utilisée pour plusieurs types d'importations, donc je ne traite pas les champs individuels jusqu'à ce que l'utilisateur soit prêt et me dise où le traiter. Donc, dans ce cas, j'ai une table d'importation avec beaucoup de cellules que je vais utiliser pour créer (ou mettre à jour) des donneurs dans ma table de donneurs. Comment envoyer mes données import_table associées au modèle et au contrôleur import_table à la méthode create de mes donor_controller?Comment mettre à jour un modèle (table) à partir d'un contrôleur différent (ou modèle)

la méthode create de mon donors_controller:

 def create 
     # need to find donor by id if given, else use find_or_create_by_blahblahblah 
     unless @donor = Donor.find_by_id(params[:donor][:id]) 
      @donor = Donor.find_or_initialize_by_company_and_prefix1_and_first_name1_and_last_name1_and_address1(params[:donor]) 
     end 

     if @donor.new_record? 

      respond_to do |format| 
      if @donor.save 
       format.html { redirect_to @donor, notice: 'Donor was successfully created.' } 
       format.json { render json: @donor, status: :created, location: @donor } 
      else 
       format.html { render action: "new" } 
       format.json { render json: @donor.errors, status: :unprocessable_entity } 
      end 
      end  
     else 
      respond_to do |format| 
      if @donor.save 
       format.html { redirect_to @donor, notice: 'Donor already exists. Please edit donor if needed.'} 
       format.json { render json: @donor, status: :created, location: @donor } 
      else 
       format.html { render action: "new" } 
       format.json { render json: @donor.errors, status: :unprocessable_entity } 
      end 
      end 
     end 

     end 

Puis dans mon contrôleur import_tables J'ai cette méthode:

def process_import 
    @import = ImportTable.find(params[:id]) 
    if @import.import_type == 'Prospects' 
    #do something here.... 
    elsif @import.import_type == 'Donations' 
    #do something here... 
    end 

end 

Je ne sais pas exactement ce que je dois faire dans les #do something here... parties. Je pensais que je devrais choisir les bonnes colonnes de @import et les mettre dans le tableau [: donor] et les envoyer à la méthode create de mes donor_controller, mais je ne suis pas sûr exactement comment faire ou si est la bonne façon de faire cela.

Répondre

2

Le chaînon manquant est que vous devez aller à la classe à partir de son nom ..

Il y a plusieurs façons de le faire, par exemple avec un « eval », mais plus propre et plus simple façon de le faire est de:

# do something: 
    class_name = @import.import_type 
    klass = ActiveRecord.const_get(class_name) # now you have a reference to your class 

    #... then do whatever you like with your symbolic klass, e.g. create your new entry 
    # klass.find_or_create(...) , klass.find(1), klass.first , 
    # klass.create({attributes for new instance of klass}) 

cela fonctionne si facilement parce que dans votre modèle vous YourClass < ActiveRecord :: Base, votre classe fait partie de la ActiveRecord module, les Classes dans Ruby sont des constantes qui sont stockées dans le contexte dans lequel elles sont définies (= dans leur module), donc vous pouvez interroger ce contexte, par exemple ActiveRecord, et trouver votre classe

Si votre classe n'a pas été dérivée de ActiveRecord :: Base, vous pouvez toujours faire un:

klass = Kernel.const_get(class_name) 

voir aussi: http://infovore.org/archives/2006/08/02/getting-a-class-object-in-ruby-from-a-string-containing-that-classes-name/

+0

Je suis d'accord, c'est la bonne façon ... –

1

si vous allez ligne par ligne, comptez le nombre de lignes que vous traitez.

puis dans vos zones #Ne quelque chose simplement appeler Prospect.new, Donation.new, etc.

validate ou l'enregistrer, et cueillant toutes les erreurs signalées par l'objet afin que vous puissiez les recracher à l'utilisateur avec un numéro de ligne où l'erreur s'est produite.

Vous n'avez pas besoin d'accéder aux méthodes de contrôleur spécifiques pour chaque type. Votre logique d'importation va essentiellement le gérer.

Questions connexes