Rails的开发和生产环境之间有什么重要的区别?

由于Rail的生产和开发环境之间存在差异,我今天遇到了一个可怕的问题。 考虑一下代码:

"select * from subscription_plans where affiliate_id is null or affiliate_id = #{@subscription_plan.affiliate.id rescue 0};" 

永远不会有任何id为0的关联公司,所以如果@ subscription_plan.affiliate是nill,我希望查询只返回没有关联公司的订阅计划。 在开发环境中工作得很好,因为nil.id会抛出一个错误(前提是它确实给出了一些关于它的消息应该错误地为4)。 问题是,我将该代码实时推送到我的生产服务器,并且affiliate_id为4的订阅计划开始全部显示。 在生产中,nil.id不会抛出错误,而是简单地返回4. Geez,谢谢rails。

所有这些问题,作为Rails开发人员,我应该注意哪些其他事项? 特别是,环境之间是否存在可能导致问题的其他差异?

生产和开发之间的所有不同都是可配置的。 如果您想要生产中的whil nil ,请将其添加到您的production.rb文件中:

 # Log error messages when you accidentally call methods on nil. config.whiny_nils = true 

只需查看config/environments/production.rbconfig/environments/development.rb文件,阅读有关所用方法/属性的注释和文档。 在我的头顶,这里有一些差异:

  1. 代码不会在生产中重新加载,因此如果您有任何常量设置为Time.now1.day.ago或开发中按预期工作的任何常量,它们将无法在生产中使用。
  2. 生产中将忽略debug级别日志消息。
  3. 缓存仅在生产中启用
  4. 详细错误消息仅在开发中可用(尽管它们已记录到rails日志中)

可能还有更多,但如果你只是查看配置文件,你应该知道差异是什么。

此外,简短的代码批评:

  1. rescue foo模式通常是一个坏主意。 可能已经引发的合法错误将被忽略。
  2. 使用ActiveRecord SQL插值将动态值添加到SQL字符串,不要使用#{}

首先,我不相信这是生产与开发的问题。 您是否在每个环境中使用不同版本的Ruby? 如果是这样,那么我建议使用RVM为两者使用相同的版本。

其次,您应该有一个镜像生产服务器的临时环境。 如果您没有在同一个克隆上进行测试,那么推向生产是非常糟糕的做法。

最后,您的代码应该重构以更好地使用ActiveRecord:

 class SubscriptionPlan < ActiveRecord::Base belongs_to :affiliate end 

用法...

 @subscriptions = SubscriptionPlan.find(:all, :include => :affiliate) 

然后你可以这样做:

 @subscription.first.affiliate