我正在使用 Phusion Passenger 部署的 Rails 站点上进行维护工作.工作流程与标准的三层 Railsian 测试-开发-生产安排略有不同;相反,有两个单独安装的相同代码库针对并行 Oracle 数据库运行;开发站点位于 qa.domain.com,实时站点位于 www.domain.com
我在以下两个环境之间的代码片段(来自“vendors_controller.rb”,它使用 AuthenticatedSystem)中遇到了不同的行为:
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
...
如果系统无法创建相应的注册,注释之间的代码会破坏刚刚创建的用户对象。它在开发服务器上运行良好,但在生产服务器上运行良好,即使保存注册失败,用户对象也会顽固地卡在数据库周围。将更改推送到生产是上传 Controller 文件并执行
touch tmp/restart.txt
的简单问题。通过 shell 。这两个代码库在其他方面是相同的;什么可能导致这种差异?感谢您的考虑!
贾斯汀
编辑:
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
在开发过程中,这三个标志被设置为其相反的值。谢谢!
最佳答案
您应该考虑更改代码的一些事项:
话虽如此,您出现问题的原因可能是由于生产和开发之间的环境差异,很可能是这样的:
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
操作很可能非常简单,您可以将 Controller 切换为使用 inherited resources .我希望这有帮助!
关于ruby-on-rails - rails : Different behavior on dev and production,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2454734/