Rails: various behavior on dev and production

I'm doing maintenance work on a Rails site that has been deployed using Phusion Passenger . The workflow is slightly different from the standard three-level Railsian testing method-dev-production; instead, there are two separate installations of the same code base, working with parallel Oracle databases; the dev website is on qa.domain.com and the website is at www.domain.com

I experience a different behavior in the following code fragment (from 'vendors_controller.rb' that uses AuthenticatedSystem) between two environments:

def create @user = current_user || User.new(params[:user]) @registration = Registration.new(params[:registration]) unless current_user @user.user_type = 'vendor' @user.active = 1 if @user.save @user.activate! @user.has_role 'owner', @user @user.has_role 'vendor' self.current_user = user = @user @registration.active = 1 @registration.email = @user.email @registration.user_id = @user.id if @registration.save send_confirmation(@user) send_solicitations_notifications(@registration) if @registration.notification_desired == true redirect_to thank_you_vendors_path else # THIS BEHAVIOR DIFFERS ACROSS PRODUCTION AND DEVELOPMENT @user.destroy self.current_user = user = nil # END DIFFERENCE respond_to do |format| format.html { render :action => 'new' } format.xml { render :xml => @registration.errors, :status => :unprocessable_entity } end end else respond_to do |format| format.html { render :action => 'new' } format.xml { render :xml => @user.errors, :status => :unprocessable_entity } end end ... 

The code between the comments destroys the user object that was just created if the system was unable to create the corresponding registration. It works fine on the development server, but not on the production server, where the User object stubbornly hangs around the database, even if the registration is not saved. Pushing changes during production is a simple matter of downloading the controller file and executing touch tmp/restart.txt through the shell. Otherwise, the two codes are identical; what can cause this difference?

Thank you for your attention!

Justin

EDIT: There are several differences in production.rb from two installations that can help diagnose the problem. In 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 

and in development, these three flags are set to their inverse values. Thanks!

+4
source share
1 answer

There are a few things you should consider changing the code:

  • You are not using transactions.
  • You do too much in the controller

Having said that the reason why you are a problem is probably due to differences in the environment between production and development, most likely this:

 config.cache_classes = false 

However, I do not think that you should change this during the production process, as this will slow down all your actions. Instead, I recommend having an intermediate environment that exactly matches your work environment.

To fix your problem, I would most likely rewrite the action as follows:

 # 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 

nb I have not tested this, this may not work, but you should get an idea ... if you have unit tests (which I hope you will do it ...), you should miss it and see if it works!

The next step is to use accepts_nested_attribute_for for your registration object so that it can be represented as part of the user settings.

I would also reorganize this to all role settings, etc. performed in callbacks .

At this point, your create action is likely to be very simple, and you can switch your controller to use inherited resources .

Hope this helps!

+1
source

Source: https://habr.com/ru/post/1304260/


All Articles