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

时间:2011-01-19 18:35:43

标签: ruby-on-rails activerecord development-environment

由于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开发人员,我应该注意哪些其他事项?特别是,环境之间是否存在可能导致问题的其他差异?

2 个答案:

答案 0 :(得分:5)

生产和开发之间的所有不同都是可配置的。如果您想在制作中加入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. 生产中会忽略
  3. debug级日志消息。
  4. 缓存仅在生产中启用
  5. 详细错误消息仅在开发中可用(尽管它们已记录到rails日志中)
  6. 可能还有更多,但如果你只是查看配置文件,你应该知道差异是什么。

    另外,简短的代码批评:

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

答案 1 :(得分:0)

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

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

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

class SubscriptionPlan < ActiveRecord::Base
  belongs_to :affiliate
end

...用法

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

然后你可以做类似的事情:

@subscription.first.affiliate