4

Je fais des travaux de maintenance sur un site Rails qui est déployé en utilisant Phusion Passenger. Le workflow est un peu différent de l'arrangement standard de test-dev-production à trois niveaux de Railsian; à la place, il existe deux installations distinctes de la même base de code exécutées sur des bases de données Oracle parallèles; Le site de développement réside sur qa.domain.com, et le site en direct sur www.domain.comRails: comportement différent sur le développement et la production

Je rencontre un comportement différent dans l'extrait de code suivant (de 'vendors_controller.rb', qui utilise AuthenticatedSystem) entre le deux environnements:

le code entre les commentaires détruit l'objet utilisateur vient d'être créé si le système n'a pas pu créer un enregistrement correspondant. Cela fonctionne correctement sur le serveur de développement mais pas sur le serveur de production, où l'objet Utilisateur reste obstinément dans la base de données même si l'enregistrement échoue. Pousser les changements à la production est une simple question de télécharger le fichier de contrôleurs et faire touch tmp/restart.txt via le shell. Les deux bases de code sont par ailleurs identiques; qu'est-ce qui pourrait causer cette différence?

Merci de votre considération!

Justin

EDIT: Il y a quelques différences dans production.rb entre les deux installations qui pourraient aider à diagnostiquer le problème. En production,

config.cache_classes = true 

# Full error reports are disabled and caching is turned on 
config.action_controller.consider_all_requests_local = false 
config.action_controller.perform_caching    = true 

en cours de développement, ces trois indicateurs sont mis à leurs valeurs inverses. Merci!

Répondre

1

Il y a quelques choses que vous devriez envisager de changer votre code:

  1. Vous n'êtes pas en utilisant les transactions
  2. Vous faites beaucoup trop dans le contrôleur

Cela dit que la raison pour laquelle vous avez un problème est probablement due aux différences d'environnement entre la production et le développement, probablement:

config.cache_classes = false 

Cependant, je ne pense pas que vous devriez changer cela en production car cela ralentira toutes vos actions. Je recommande plutôt d'avoir un environnement intermédiaire qui correspond étroitement à votre environnement de production.

Pour résoudre votre problème, je réécris le plus probablement l'action comme ceci:

# using before filters will keep your actions tight 
before_filter :cannot_create_user, :if => :signed_in? 

def create 
    # setup all the objects 
    @user = User.new(params[:user]) 

    @user.user_type = 'vendor' 
    @user.active = 1 

    @user.has_role 'owner', @user 
    @user.has_role 'vendor' 

    @registration = @user.registrations.build(params[:registration]) 
    @registration.active = 1 
    @registration.email = @user.email 

    # make sure everything is valid before trying to save and activate 
    if @user.valid? 
    @user.save! # might not need this if activate calls save! 
    @user.activate! 

    # this should probably be a sign_in() method... 
    self.current_user = @user 

    send_confirmation(@user) 
    send_solicitations_notifications(@registration) if @registration.notification_desired? 

    redirect_to thank_you_vendors_path 
    else 
    respond_to do |format| 
     format.html { render :action => 'new' } 
     format.xml { render :xml => @registration.errors, :status => :unprocessable_entity } 
    end 
    end 

... 
end 


protected 

def signed_in? 
    !current_user.nil? 
end 

def cannot_create_user 
    respond_to do |format| 
    format.html { render :action => 'new' } 
    format.xml { render :xml => @user.errors, :status => :unprocessable_entity } 
    end 
end 

N.B. Je n'ai pas testé ça, ça pourrait ne pas fonctionner, mais vous devriez avoir l'idée ... si vous avez des tests unitaires (ce que j'espère que vous faites ...), vous devriez pouvoir le laisser tomber et voir si ça marche!

Votre prochaine étape serait d'utiliser l'utilisation accepts_nested_attribute_for pour votre objet d'enregistrement, afin qu'il puisse être soumis dans le cadre des paramètres de l'utilisateur.

Je refactoriserais aussi ceci pour que tous les paramètres de rôle etc ... soient faits dans callbacks.

À ce stade, votre action create sera probablement très simple et vous pouvez changer votre contrôleur pour utiliser inherited resources.

J'espère que cela aide!

+0

Merci pour la réponse, jonnii ... très appréciée! Je n'ai pas écrit le code moi-même - je ne fais que le déboguer - mais votre solution est beaucoup plus élégante. En outre, il s'avère que le problème était avec Phusion Passenger; J'avais renommé l'ancienne version du fichier en 'vendors_controller_031610.rb' au cas où je devrais revenir rapidement et il s'avère que Phusion utilisait le contrôleur obsolète, même après avoir été redémarré. La suppression de l'ancien fichier a résolu le problème. Étrange, hein? – justinbach

Questions connexes