4

我在使用Phusion Passenger部署的Rails站点上进行维护工作。工作流程与标准的三层Railsian测试开发生产安排稍有不同;相反,针对并行Oracle数据库运行的是相同代码库的两个单独安装;开发网站的生活在qa.domain.com,并在www.domain.com网站Rails:在开发和生产上的不同行为

我在下面的代码片段(来自'两个环境:

代码中的注释之间破坏刚创建的用户对象,如果该系统无法创建相应的注册。它在开发服务器上工作正常,但不在生产服务器上,即使保存注册失败,用户对象仍顽固地挂在数据库周围。将更改推送到生产是一个简单的事情,即上传控制器文件并通过shell执行touch tmp/restart.txt。这两个代码库在其他方面是相同的;什么可能导致这种差异?

感谢您的考虑!

贾斯汀

编辑:有在production.rb横跨两个安装一些差异,可能会帮助诊断问题。在生产时,

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 

在开发时,这三个标志被设置为它们的反值。谢谢!

回答

1

有你应该考虑改变你的代码的几件事情:

  1. 您没有使用交易
  2. 你做了太多的控制器

说罢你出现问题的原因可能是由于生产和开发之间的环境差异造成的,最有可能是这样的:

config.cache_classes = false 

但是,我认为你不应该在生产中改变它,因为它会减慢你的所有行动。相反,我建议有一个与您的生产环境非常匹配的临时环境。

解决您的问题,我想最有可能改写这样的动作:

# 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 

注:我没有测试这个,它可能不起作用,但你应该明白......如果你有单元测试(我希望你这样做),你应该能够放下它,看看它是否工作!

您的下一步将使用使用accepts_nested_attribute_for作为您的注册对象,以便它可以作为用户参数的一部分提交。

我也会重构这个,以便所有的角色设置等都在callbacks完成。

此时,您的create操作很可能非常简单,您可以切换控制器以使用inherited resources

我希望这有助于!

+0

感谢您的回应,jonnii ...非常感谢!我没有自己写代码 - 我只是在调试它 - 但是你的解决方案更加优雅。另外,事实证明问题出在Phusion Passenger上;我想将旧版本的文件重命名为“vendors_controller_031610.rb”,以防万一需要快速恢复,并且事实证明Phusion即使在重新启动后也使用过时的控制器。删除旧文件解决了问题。奇怪,呃? – justinbach 2010-03-16 15:10:57

相关问题