如何判断ActiveRecord“where”方法是创建新行还是获取现有行?

时间:2015-04-09 03:15:22

标签: ruby-on-rails ruby-on-rails-4 activerecord

如何判断以下代码是创建新记录还是返回现有记录?我假设where方法在此处创建新用户(如果不存在)。

# Create User Model Instance
user = User.where(:provider => auth["provider"], :uid => auth["uid"]).first_or_initialize(
  :refresh_token => auth["credentials"]["refresh_token"],
  :access_token => auth["credentials"]["token"],
  :expires => Time.at(auth["credentials"]["expires_at"]).to_datetime,
  :expires_str => auth["credentials"]["expires_at"],
  :name => auth["info"]["name"],
)

# Save User
if user.save
  session[:user_id] = user.id
  notice = "Signed in!"
  logger.debug "URL to redirect to: #{url}"
  redirect_to url, :notice => notice
else
  raise "Failed to login"
end

1 个答案:

答案 0 :(得分:3)

  

我假设where方法在此处创建新用户(如果不存在)。

那是错的。 where永远不会创建新行,只能用于查询记录。

这种方法的工作方式是,first_or_initialize找到第一个匹配的记录,或者如果找不到,则会提示新的未保存的记录。在这种情况下,数据库中没有新记录

接下来,您致电user.save! 在没有存在的情况下创建记录。 where与记录的创作无关。

至于告知ActiveRecord对象是来自数据库还是仅存在于内存中,您正在寻找persisted?。如果对象尚未保存到数据库,则返回false。

# Create User Model Instance
user = User.where(:provider => auth["provider"], :uid => auth["uid"]).first_or_initialize(
  :refresh_token => auth["credentials"]["refresh_token"],
  :access_token => auth["credentials"]["token"],
  :expires => Time.at(auth["credentials"]["expires_at"]).to_datetime,
  :expires_str => auth["credentials"]["expires_at"],
  :name => auth["info"]["name"],
)

# At this point, if user.persisted? is true, the user was found in the database.
# The below call to `save` will update the record.
# OR
# If false, the user doesn't exist in the database yet.
# The below call to save will insert the record

# Save User
if user.save
  session[:user_id] = user.id
  notice = "Signed in!"
  logger.debug "URL to redirect to: #{url}"
  redirect_to url, :notice => notice
else
  raise "Failed to login"
end