10 most underused activerecord relation methods(翻译)

2016/05/20 Rails

10.first_or_create with a block

常用的first_or_create:

Book.where(title: 'Tale of Two Cities').first_or_create

一般情况,你想要通过一个确定的属性找到一个记录,或者用增加的这个属性新建一个记录。 你可以通过block来使用first_or_create:

Book.where(:title => 'Tale of Two Cities').first_or_create do |book|
  book.author = 'Charles Dickens'
  book.published_year = 1859
end

当你没找到相应数据的时候,这里的操作就相当于:

Book.create(title: 'Tale of Two Cities',
            author: 'Charles Dickens',
            published_year: 1859)

传的三个属性都将用于create操作

同样的,find_or_create_by 也可以进行block的操作

9.first_or_initialize

如果你还不想要save这条记录,可以使用first_or_initialize:

Book.where(:title => 'Tale of Two Cities').first_or_initialize

和first_or_create 一样,你也可以使用 block方式,增加更多的属性。

8.scoped

有时候你想要用 ActiveRecord::Relation 表示一个类的所有数据记录,你可以很容易的使用scoped方法构造出来:

def search(query)
  if query.blank?
    scoped
  else
    q = "%#{query}%"
    where("title like ? or author like ?", q, q)
  end
end

7.none(rails 4 only)

同样的,有时候你想要用 ActiveRecord::Relation 表示没有对象。如果客户的API 期望关系对象,返回一个空数组不是一个号的方法。你可以用 none 代替表示。

def filter(filter_name)
  case filter_name
  when :all
    scoped
  when :published
    where(:published => true)
  when :unpublished
    where(:published => false)
  else
    none
  end
end

6.find_each

如果你想要遍历成千上万的数据记录,用each已经不合适。它会执行一次查询去获得所有的数据记录,然后把它们实例化后存入内存。如果你有足够的内存去使用,可以这么做。否则,这非常容易让Rails app处于负载假死而崩溃。 find_each相反。获取一批数据记录一次默认(1000)和实例化这一次,这样你没有把所有记录实例化存入内存中。

Book.where(:published => true).find_each do |book|
  puts "Do something with #{book.title} here!"
end

请注意,您不能指定的顺序由find_each记录了。如果你指定一个关系,它会被忽略。(意思似乎是: 无法给记录进行order排序)

5.to_sql and explain

ActiveRecord是很棒的,但它并不总是你认为它会生成查询。跳在控制台中,您正在构建的关系上运行这些命令,以确保它映射到一个智能查询,或者使用您制作精良的指标:

Library.joins(:book).to_sql
# => SQL query for you database.
Libray.joins(:book).explain
# => Database explain for the query.


4.find_by(rails 4 only)

Book.where(:title => 'Three Day Road', :author => 'Joseph Boyden').first

Book.find_by(:title => 'Three Day Road', :author => 'Joseph Boyden')

3.scoping

你可以“范围”一个类的方法到一个特定的关系。考虑下面的例子从Rails文档:

Comment.where(:post_id => 1).scoping do
  Comment.first # SELECT * FROM comments WHERE post_id = 1
end

2.pluck and ActiveRecord::Base.connection.select_all

想要对某些记录数组的列值吗?使用pluck

published_book_titles = Book.published.pluck(:title)

想要得到记录以hash的结构形式返回,使用ActiveRecord::Base.connection.select_all

ActiveRecord::Base.connection.select_all('SELECT * FROM users')

1.merge

我不能没有这个宝石,但奇怪的是un-documented源,而不是我见过任何指导或书中提到。其他用途,它可以让你做一个连接,通过命名范围和过滤加入模型:

class Account < ActiveRecord::Base
  # ...

  # Returns all the accounts that have unread messages.
  def self.with_unread_messages
    joins(:messages).merge( Message.unread )
  end
end

原文: http://www.mitchcrowe.com/10-most-underused-activerecord-relation-methods/

Search

    Table of Contents