find

返回一条或多条记录

只能按id查找,即是参数为数字

找不到记录会报错(既然都给到id了,那应该是期望它存在,所以不存在的话,应该raise)

# activerecord-5.0.2/lib/active_record/core.rb
def find(*ids) # :nodoc:
  # We don't have cache keys for this stuff yet
  return super unless ids.length == 1
  return super if block_given? ||
                  primary_key.nil? ||
                  scope_attributes? ||
                  columns_hash.include?(inheritance_column) ||
                  ids.first.kind_of?(Array)

  id  = ids.first
  if ActiveRecord::Base === id
    id = id.id
    ActiveSupport::Deprecation.warn(<<-MSG.squish)
      You are passing an instance of ActiveRecord::Base to `find`.
      Please pass the id of the object by calling `.id`.
    MSG
  end

  key = primary_key

  statement = cached_find_by_statement(key) { |params|
    where(key => params.bind).limit(1)
  }
  record = statement.execute([id], self, connection).first
  unless record
    raise RecordNotFound.new("Couldn't find #{name} with '#{primary_key}'=#{id}",
                             name, primary_key, id)
  end
  record
rescue RangeError
  raise RecordNotFound.new("Couldn't find #{name} with an out of range value for '#{primary_key}'",
                           name, primary_key)
end


find_by

也只返回一条记录(first)

参数一般为hash,如{id: 99}

# activerecord-5.0.2/lib/active_record/core.rb
def find_by(*args) # :nodoc:
  return super if scope_attributes? || reflect_on_all_aggregations.any?

  hash = args.first

  return super if !(Hash === hash) || hash.values.any? { |v|
    v.nil? || Array === v || Hash === v || Relation === v || Base === v
  }

  # We can't cache Post.find_by(author: david) ...yet
  return super unless hash.keys.all? { |k| columns_hash.has_key?(k.to_s) }

  keys = hash.keys

  statement = cached_find_by_statement(keys) { |params|
    wheres = keys.each_with_object({}) { |param, o|
      o[param] = params.bind
    }
    where(wheres).limit(1)
  }
  begin
    statement.execute(hash.values, self, connection).first
  rescue TypeError
    raise ActiveRecord::StatementInvalid
  rescue RangeError
    nil
  end
end


find_by!

同find_by,但找不到记录会报错

def find_by!(*args) # :nodoc:
  find_by(*args) or raise RecordNotFound.new("Couldn't find #{name}", name)
end


find_by_xx

首次执行会动态定义一个方法名为find_by_xx,方法体为find_by({xx: yy})的方法,即是效果同find_by。其运作如下

find_by_xx.html

where

返回的是ActiveRecord::Relation