开发新手最容易犯的50个 Ruby on Rails 错误(1)

【编者按】本文最早发布与 JETRuby 博客,主要介绍了开发新手最容易犯的 Ruby 错误。文章系国内 ITOM 管理平台 OneAPM 编译呈现。

一年前,我们创立了以 “Rubyboost” 为名的 Ruby on Rails 课程。简而言之,本课程的目标是使对编程了解不多的新手也能在两个月内,提升技能、成为初级开发者。在成功完成课程之后,学生会收到为其两个月的实习邀请,实习地点就在我们公司。如果一切顺利,就会得到聘用。不得不说,这是一种相对公平且简单的成为职业开发者的道路,你觉得呢?

顺带说一句,你根本想不到,有多少人愿意来参加并学习 Rails 编程!

在分析了所有受训者编写的代码之后,我们总结了50个最常见的错误!更糟糕的是,每个小组所犯的错误与前一组的错误几乎一模一样。

以下是 Rails 新手常常忽略或做错的地方。我们还包含了“对“,”错”两个版本的代码样本,使得教程更为清楚。

1、他们不使用自动生成的方法

############
## WRONG ##
############  

if course.visible
  # do something
  end

##############
##  RIGHT   ##
##############  

if course.visible?
  # do something
  end

通常,Rails 和许多 gems 会为它们使用的对象添加一些有用的帮助方法。例如,Rails 会自动为布尔字段添加声明。通常,这些方法的名字是以问号结尾的。请牢记这一点!

2、他们不知道“N+1”查询来自何处

#############
##  WRONG  ##
#############  

 @homeworks = lesson.homeworks

  - @homeworks.each do |homework|
    %p homework.user.email

#############
##  RIGHT  ##
#############  

  @homeworks = lesson.homeworks.includes(:user)

  - @homeworks.each do |homework|
    %p homework.user.email

了解 ORM 如何与数据库交互是非常重要的。但是,新手往往没有这种了解。因此,他们很少使用 “includes”、“preload” 与 “eager_load” 这类方法,并且对 “bullet” gem 一无所知。

在第一个例子中,N+1 查询会传递至数据库。”N” 是已经完成的家庭作业数量。查询数量可能是10、20甚至100。而在第二个例子中,只有2个查询!

3、他们不用 scopes(域)

############
## WRONG  ##
############  

def index
  @lessons = Сourse.lessons.order(position: :asc)
end

############
##  RIGHT ##
############  

class Lesson < ActiveRecord::Base
    belongs_to :course

    scope :by_position, -> { order(position: :asc) }
 end  

 def index
   @lessons = course.lessons.by_position
 end

Scopes 允许你隐藏数据库的实现,并将代码唯一化(uniqualize)。而且,代码的可读性也会大幅提升,因为他们透露了开发者的意图,而非数据库的结构。

4、他们不了解 “after_create” 与 “after_commit” 间的差别

模型的数据,包括其在 “after_create” 中的新 ID,可以从内部,而非外部进行读取,原因是交易尚未完成。

如果我在数据库中创建了一条记录,之后打算将其 ID 放入 redis 或任意的存储中,会得到以下结果:

  • 如果 ID 在交易完成之前使用,“after_create” 可能会导致无效数据。
  • 借助 “Sidekiq” 或其他任意后台工作,我总是可以使用 “after_commit” 确保数据的完整性。

5、他们总是使用 ORM

#############
##  WRONG  ##
#############

  Article.all.each { |article| article.delete }

  Article.all.map { |article| article.title }

  Course.all.select { |course| course.created_at < 5.years.ago }.each { |course| course.articles.delete_all }

  #############
  ##  RIGHT  ##
  #############

  Article.delete_all

  Article.pluck(:title)

  old_courses_ids = Course.where(‘created_at < ?’, 5.years.ago’).pluck(:id)
  Article.where(course_id: old_courses_ids).delete_all

尽管使用对象无疑非常方便,但整个过程却非常缓慢,而且需要很多内存。新手们可能并不理解代码的工作原理,以及如何提高其效率。

6、他们不了解 “dependent destroy” 与 “delete_all” 的区别

在被移除之前,“dependent destroy” 会选择所有受限记录,建立其对象,并调用各自的毁灭方法。此方法允许你移除所有受限数据。但是,当涉及大量数据时,这种方法就不管用了。

至于 “dependent delete_all”,它会通过一条 SQL 查询移除自己。它效率很高,但是,在这种情况下,你得自己考虑数据库的完整性。

7、他们不用带 bang 的方法

#############
##  WRONG  ##
#############

  class Article
    validates :body, length: { minimum: 200 }
  end

  articles_data.each do |article_data|
    Article.create(article_data)
  end

#############
##  RIGHT  ##
#############  

# There are 2 possible solutions

  articles_data.each do |article_data|
    Article.create!(article_data)
  end  

  # In this case a developer will be able to see that data he was not expencting to receive will get on the input

  articles_data.each do |article_data|
    article = Article.new(article_data)

    unless article.save
      puts ‘Can not save article’
      #process this situation
     end
   end
# Give a user a choice.

根据协议,将 bang(!) 添加至方法名的情况有如下两种:

  • 如果某个方法修改了其访问的对象
  • 如果某个方法在执行失败后抛出了异常

新手们常常忽略第二种情况。如果代码出了问题,你必须尽快找到问题根源。例如,如果完全不处理将记录保存至数据库的结果,最好还是抛出异常以找到哪段代码处理了无效数据。

在上例中,如果一个无效的物品传给输入,就会被忽视。

8、他们不在迁移中设置默认字段

#############
##  WRONG  ##
#############  

class Article
    after_initialize :set_default_status    

    def set_default_status
      self.status = ‘pending’
        end
      end

#############
##  RIGHT  ##
#############  

class MyMigration
   def up
      change_column :articles, status, :string, default: ‘pending’
    end    

  def down
      change_column :articles, status, :string
    end
  end

如果字段中的某个模型必须要有一个默认值,应该通过数据库进行安装。

9、他们不在迁移中设置限制条件

#############
##  WRONG  ##
#############  

class MyMigration
  def change
      add_column :profiles, user_id, :integer
    end
  end

#############
##  RIGHT  ##
#############  

class MyMigration
def change
      add_column :profiles, user_id, :integer, null: false
   end
 end

对于基础架构的限制条件越多,我们的应用就会越可靠。此外,别忘记 “null:false”,用户不可以没有简介。

10、他们不在迁移中写反向迁移

如果不能回滚,迁移的意义在哪儿?

以上是新手们最常犯的 Ruby on Rails 错误的第一部分,如果喜欢本文,请记得分享哦。

未完待续……

本文转自 OneAPM 官方博客

原文地址:http://jetruby.com/expertise/common-ruby-rails-mistakes-beginners-make-model-database/

时间: 2024-09-15 14:16:53

开发新手最容易犯的50个 Ruby on Rails 错误(1)的相关文章

10个常见的Android开发新手误区

  1.不读Android开发文档 Android开发者网站可以很好的帮助你.很多的文档也可以通过SDK工具下载.这些文档不仅仅是Javadoc API的参考,它包括许多指南.教程.视频.培训以及其他有用的资料来创建Android应用程序. Android训练,通过一些有用的教程示例,指导你解决特定问题或实现特定的功能. 2.不熟悉Android开发工具 Android SDK不仅可以用来编译打包你的应用程序在Android手机上运行,而且它有一整套工具来帮助你构建应用程序.其中一些工具可以帮助

Android开发新手常见的10个误区_Android

在过去十年中最流行的移动应用开发开发平台中,我们认为,Android平台是一个新开发的最方便的平台.一个廉价的工具,友好的开发者社区,众所周知的编程语言(Java),使得开发Android应用程序从未如此简单.即便如此,我们仍然看到了哪些新的Andr​​oid开发人员不断重复的错误.这里有10个最常见的误区. 1,阅读Andr​​oid文档 Android开发者网站是你获得帮助的最重要地方.大部分的文档既可以随着SDK下载,也可在网上直接查阅(我们推荐在线浏览,因为它是不断更新的).这些文档是不

Android开发新手常见的10个误区

在过去十年中最流行的移动应用开发开发平台中,我们认为,Android平台是一个新开发的最方便的平台.一个廉价的工具,友好的开发者社区,众所周知的编程语言(Java),使得开发Android应用程序从未如此简单.即便如此,我们仍然看到了哪些新的Andr​​oid开发人员不断重复的错误.这里有10个最常见的误区. 1,阅读Andr​​oid文档 Android开发者网站是你获得帮助的最重要地方.大部分的文档既可以随着SDK下载,也可在网上直接查阅(我们推荐在线浏览,因为它是不断更新的).这些文档是不

移动开发-新手求助objective-c,请教下我吧

问题描述 新手求助objective-c,请教下我吧 新手求助为什么出现这样的问题,求指导,试来试去都是这样,高手们可以告诉告诉我嘛?开发-新手求助objective-c,请教下我吧-田字格ps新手求助"> 解决方案 你的app ID需要先在app store的账号上绑定 解决方案二: 非常感谢你了

游戏开发-新手使用cocos2d遇到问题,求帮忙

问题描述 新手使用cocos2d遇到问题,求帮忙 编译错误信息如图,图中EActorType确定已经声明,切头文件已经包含,求帮忙开发-新手使用cocos2d遇到问题,求帮忙-遇到杀人该去帮忙吗"> 解决方案 头文件还是没包含正确 你编译器中对应头文件能右键打开吗 解决方案二: http://bbs.csdn.net/topics/391901732

java web-Java Web开发新手请教个问题(eclipse第三方jar的正确导入方式)

问题描述 Java Web开发新手请教个问题(eclipse第三方jar的正确导入方式) 比如我导入第三方jar包, 我在JSP页面用了这个包,eclipse编译倒是通过.但浏览器弹出来就显示XXX cannot be resolved to a type. 我是这样导入的:右击项目,Build Path-->Libraries-->Add External JARS,还有我把该jar包也放在项目中的WEB-INF的Lib文件下了,还是没用. 凡是用到第三方包,eclipse编译都通过,浏览器

web前端开发JQuery常用实例代码片段(50个)_jquery

本文给大家展示50个jquery代码片段,这些代码能够给你的javascript项目提供帮助.其中的一些代码段是从jQuery1.4.2才开始支持的做法,另一些则是真正有用的函数或方法,他们能够帮助你又快又好地把事情完成.这些都是我尽量记住的有着最佳性能的代码段,因此如果你发现你任何可以做得更好的地方的话,欢迎把你的版本粘贴在评论中!我希望你在这一文章中能找到有帮助的东西. 1. 如何创建嵌套的过滤器 //允许你减少集合中的匹配元素的过滤器, //只剩下那些与给定的选择器匹配的部分.在这种情况下

微信支付接口开发新手常见问题解决

今天,我下载了官方文档,直接用官方demo(php版本)做了个简单支付页面.遇到了下面问题. 1.配置文件修改 找到配置文件WxPay.Config.php,只需要配置下面四项 开发新手常见问题解决-面包烘焙新手常见问题"> 2.redirect_uri参数错误 登陆公众管理后台-点击开发者中心-找到网页帐号点击修改,写自己域名,保存生效. 3.页面URL未注册 登陆公众微信后台-微信支付-开发配置,支付授权目录路径一直到最后一个斜杠 我设置的测试授权目录是:http://www.xxx.

企业重新设计网站或开发新网站所犯的12大错误

摘要: 建立商业网站可能在很多地方都会出错.为了找出企业重新设计网站或开发新网站所犯的最大的错误,CIO调查了网站开发者.设计者和客户体验专家,我们引用了12条最常见的问题,并 建立商业网站可能在很多地方都会出错.为了找出企业重新设计网站或开发新网站所犯的最大的错误,CIO调查了网站开发者.设计者和客户体验专家,我们引用了12条最常见的问题,并告诉你怎样修复或避免这些问题. 错误1. 忘了你的客户是谁.你的高级管理团队不是你的客户,你的顾客才是.但是企业太经常忘记了,于是他们创造出来的东西不是客