diff --git a/app/controllers/admin/api_controller.rb b/app/controllers/admin/api_controller.rb
index 82aef9103f9..472b4b9c3e6 100644
--- a/app/controllers/admin/api_controller.rb
+++ b/app/controllers/admin/api_controller.rb
@@ -5,7 +5,7 @@ class Admin::ApiController < Admin::AdminController
   end
 
   def regenerate_key
-    api_key = ApiKey.where(id: params[:id]).first
+    api_key = ApiKey.find_by(id: params[:id])
     raise Discourse::NotFound.new if api_key.blank?
 
     api_key.regenerate!(current_user)
@@ -13,7 +13,7 @@ class Admin::ApiController < Admin::AdminController
   end
 
   def revoke_key
-    api_key = ApiKey.where(id: params[:id]).first
+    api_key = ApiKey.find_by(id: params[:id])
     raise Discourse::NotFound.new if api_key.blank?
 
     api_key.destroy
diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb
index a826b4a0762..3c4de5d9aaa 100644
--- a/app/controllers/admin/users_controller.rb
+++ b/app/controllers/admin/users_controller.rb
@@ -27,13 +27,13 @@ class Admin::UsersController < Admin::AdminController
   end
 
   def show
-    @user = User.where(username_lower: params[:id]).first
+    @user = User.find_by(username_lower: params[:id])
     raise Discourse::NotFound.new unless @user
     render_serialized(@user, AdminDetailedUserSerializer, root: false)
   end
 
   def delete_all_posts
-    @user = User.where(id: params[:user_id]).first
+    @user = User.find_by(id: params[:user_id])
     @user.delete_all_posts!(guardian)
     render nothing: true
   end
@@ -157,7 +157,7 @@ class Admin::UsersController < Admin::AdminController
   end
 
   def destroy
-    user = User.where(id: params[:id]).first
+    user = User.find_by(id: params[:id])
     guardian.ensure_can_delete_user!(user)
     begin
       if UserDestroyer.new(current_user).destroy(user, params.slice(:delete_posts, :block_email, :block_urls, :block_ip, :context))
@@ -180,7 +180,7 @@ class Admin::UsersController < Admin::AdminController
   private
 
     def fetch_user
-      @user = User.where(id: params[:user_id]).first
+      @user = User.find_by(id: params[:user_id])
     end
 
     def refresh_browser(user)
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 7bae7c5fde1..7fa94a656f1 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -203,7 +203,7 @@ class ApplicationController < ActionController::Base
     username_lower = params[:username].downcase
     username_lower.gsub!(/\.json$/, '')
 
-    user = User.where(username_lower: username_lower).first
+    user = User.find_by(username_lower: username_lower)
     raise Discourse::NotFound.new if user.blank?
 
     guardian.ensure_can_see!(user)
diff --git a/app/controllers/categories_controller.rb b/app/controllers/categories_controller.rb
index 92b9d068173..41d8a051e3b 100644
--- a/app/controllers/categories_controller.rb
+++ b/app/controllers/categories_controller.rb
@@ -102,6 +102,6 @@ class CategoriesController < ApplicationController
     end
 
     def fetch_category
-      @category = Category.where(slug: params[:id]).first || Category.where(id: params[:id].to_i).first
+      @category = Category.find_by(slug: params[:id]) || Category.find_by(id: params[:id].to_i)
     end
 end
diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb
index ee8552b0982..3b5b07c6062 100644
--- a/app/controllers/groups_controller.rb
+++ b/app/controllers/groups_controller.rb
@@ -25,7 +25,7 @@ class GroupsController < ApplicationController
 
   def find_group(param_name)
     name = params.require(param_name)
-    group = Group.where("lower(name) = ?", name.downcase).first
+    group = Group.find_by("lower(name) = ?", name.downcase)
     guardian.ensure_can_see!(group)
     group
   end
diff --git a/app/controllers/invites_controller.rb b/app/controllers/invites_controller.rb
index 945a28c2352..b929a75332c 100644
--- a/app/controllers/invites_controller.rb
+++ b/app/controllers/invites_controller.rb
@@ -6,7 +6,7 @@ class InvitesController < ApplicationController
   before_filter :ensure_logged_in, only: [:destroy, :create]
 
   def show
-    invite = Invite.where(invite_key: params[:id]).first
+    invite = Invite.find_by(invite_key: params[:id])
 
     if invite.present?
       user = invite.redeem
@@ -42,7 +42,7 @@ class InvitesController < ApplicationController
   def destroy
     params.require(:email)
 
-    invite = Invite.where(invited_by_id: current_user.id, email: params[:email]).first
+    invite = Invite.find_by(invited_by_id: current_user.id, email: params[:email])
     raise Discourse::InvalidParameters.new(:email) if invite.blank?
     invite.trash!(current_user)
 
diff --git a/app/controllers/post_actions_controller.rb b/app/controllers/post_actions_controller.rb
index 1df6abc3e40..9a04cf0aa72 100644
--- a/app/controllers/post_actions_controller.rb
+++ b/app/controllers/post_actions_controller.rb
@@ -35,7 +35,7 @@ class PostActionsController < ApplicationController
   end
 
   def destroy
-    post_action = current_user.post_actions.where(post_id: params[:id].to_i, post_action_type_id: @post_action_type_id, deleted_at: nil).first
+    post_action = current_user.post_actions.find_by(post_id: params[:id].to_i, post_action_type_id: @post_action_type_id, deleted_at: nil)
 
     raise Discourse::NotFound if post_action.blank?
 
diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb
index f3c00de750f..83943160975 100644
--- a/app/controllers/posts_controller.rb
+++ b/app/controllers/posts_controller.rb
@@ -11,7 +11,7 @@ class PostsController < ApplicationController
   skip_before_filter :check_xhr, only: [:markdown,:short_link]
 
   def markdown
-    post = Post.where(topic_id: params[:topic_id].to_i, post_number: (params[:post_number] || 1).to_i).first
+    post = Post.find_by(topic_id: params[:topic_id].to_i, post_number: (params[:post_number] || 1).to_i)
     if post && guardian.can_see?(post)
       render text: post.raw, content_type: 'text/plain'
     else
@@ -208,7 +208,7 @@ class PostsController < ApplicationController
     revision = params[:revision].to_i
     raise Discourse::InvalidParameters.new(:revision) if revision < 2
 
-    post_revision = PostRevision.where(post_id: post_id, number: revision).first
+    post_revision = PostRevision.find_by(post_id: post_id, number: revision)
     post_revision.post = find_post_from_params
 
     guardian.ensure_can_see!(post_revision)
diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb
index e3dd2158862..f3e00c16b07 100644
--- a/app/controllers/search_controller.rb
+++ b/app/controllers/search_controller.rb
@@ -25,9 +25,9 @@ class SearchController < ApplicationController
       # A user is found by username
       context_obj = nil
       if search_context[:type] == 'user'
-        context_obj = klass.where(username_lower: params[:search_context][:id].downcase).first
+        context_obj = klass.find_by(username_lower: params[:search_context][:id].downcase)
       else
-        context_obj = klass.where(id: params[:search_context][:id]).first
+        context_obj = klass.find_by(id: params[:search_context][:id])
       end
 
       guardian.ensure_can_see!(context_obj)
diff --git a/app/controllers/topics_controller.rb b/app/controllers/topics_controller.rb
index a802ec86725..78e6a196da3 100644
--- a/app/controllers/topics_controller.rb
+++ b/app/controllers/topics_controller.rb
@@ -43,7 +43,7 @@ class TopicsController < ApplicationController
     begin
       @topic_view = TopicView.new(params[:id] || params[:topic_id], current_user, opts)
     rescue Discourse::NotFound
-      topic = Topic.where(slug: params[:id]).first if params[:id]
+      topic = Topic.find_by(slug: params[:id]) if params[:id]
       raise Discourse::NotFound unless topic
       return redirect_to(topic.relative_url)
     end
@@ -96,7 +96,7 @@ class TopicsController < ApplicationController
   end
 
   def update
-    topic = Topic.where(id: params[:topic_id]).first
+    topic = Topic.find_by(id: params[:topic_id])
     title, archetype = params[:title], params[:archetype]
     guardian.ensure_can_edit!(topic)
 
@@ -134,14 +134,14 @@ class TopicsController < ApplicationController
     enabled = (params[:enabled] == 'true')
 
     check_for_status_presence(:status, status)
-    @topic = Topic.where(id: topic_id).first
+    @topic = Topic.find_by(id: topic_id)
     guardian.ensure_can_moderate!(@topic)
     @topic.update_status(status, enabled, current_user)
     render nothing: true
   end
 
   def star
-    @topic = Topic.where(id: params[:topic_id].to_i).first
+    @topic = Topic.find_by(id: params[:topic_id].to_i)
     guardian.ensure_can_see!(@topic)
 
     @topic.toggle_star(current_user, params[:starred] == 'true')
@@ -158,7 +158,7 @@ class TopicsController < ApplicationController
 
   def autoclose
     raise Discourse::InvalidParameters.new(:auto_close_time) unless params.has_key?(:auto_close_time)
-    topic = Topic.where(id: params[:topic_id].to_i).first
+    topic = Topic.find_by(id: params[:topic_id].to_i)
     guardian.ensure_can_moderate!(topic)
     topic.set_auto_close(params[:auto_close_time], current_user)
     if topic.save
@@ -169,7 +169,7 @@ class TopicsController < ApplicationController
   end
 
   def destroy
-    topic = Topic.where(id: params[:id]).first
+    topic = Topic.find_by(id: params[:id])
     guardian.ensure_can_delete!(topic)
     topic.trash!(current_user)
     render nothing: true
@@ -188,7 +188,7 @@ class TopicsController < ApplicationController
 
   def remove_allowed_user
     params.require(:username)
-    topic = Topic.where(id: params[:topic_id]).first
+    topic = Topic.find_by(id: params[:topic_id])
     guardian.ensure_can_remove_allowed_users!(topic)
 
     if topic.remove_allowed_user(params[:username])
@@ -201,7 +201,7 @@ class TopicsController < ApplicationController
   def invite
     username_or_email = params[:user] ? fetch_username : fetch_email
 
-    topic = Topic.where(id: params[:topic_id]).first
+    topic = Topic.find_by(id: params[:topic_id])
     guardian.ensure_can_invite_to!(topic)
 
     if topic.invite(current_user, username_or_email)
@@ -225,7 +225,7 @@ class TopicsController < ApplicationController
   def merge_topic
     params.require(:destination_topic_id)
 
-    topic = Topic.where(id: params[:topic_id]).first
+    topic = Topic.find_by(id: params[:topic_id])
     guardian.ensure_can_move_posts!(topic)
 
     dest_topic = topic.move_posts(current_user, topic.posts.pluck(:id), destination_topic_id: params[:destination_topic_id].to_i)
@@ -237,7 +237,7 @@ class TopicsController < ApplicationController
     params.require(:topic_id)
     params.permit(:category_id)
 
-    topic = Topic.where(id: params[:topic_id]).first
+    topic = Topic.find_by(id: params[:topic_id])
     guardian.ensure_can_move_posts!(topic)
 
     dest_topic = move_posts_to_destination(topic)
@@ -276,14 +276,14 @@ class TopicsController < ApplicationController
   end
 
   def clear_pin
-    topic = Topic.where(id: params[:topic_id].to_i).first
+    topic = Topic.find_by(id: params[:topic_id].to_i)
     guardian.ensure_can_see!(topic)
     topic.clear_pin_for(current_user)
     render nothing: true
   end
 
   def re_pin
-    topic = Topic.where(id: params[:topic_id].to_i).first
+    topic = Topic.find_by(id: params[:topic_id].to_i)
     guardian.ensure_can_see!(topic)
     topic.re_pin_for(current_user)
     render nothing: true
@@ -330,7 +330,7 @@ class TopicsController < ApplicationController
   private
 
   def toggle_mute
-    @topic = Topic.where(id: params[:topic_id].to_i).first
+    @topic = Topic.find_by(id: params[:topic_id].to_i)
     guardian.ensure_can_see!(@topic)
 
     @topic.toggle_mute(current_user)
diff --git a/app/controllers/uploads_controller.rb b/app/controllers/uploads_controller.rb
index b94ec93ecae..2b7bffa06cd 100644
--- a/app/controllers/uploads_controller.rb
+++ b/app/controllers/uploads_controller.rb
@@ -23,7 +23,7 @@ class UploadsController < ApplicationController
       url = request.fullpath
 
       # the "url" parameter is here to prevent people from scanning the uploads using the id
-      if upload = Upload.where(id: id, url: url).first
+      if upload = Upload.find_by(id: id, url: url)
         send_file(Discourse.store.path_for(upload), filename: upload.original_filename)
       else
         render nothing: true, status: 404
diff --git a/app/controllers/user_badges_controller.rb b/app/controllers/user_badges_controller.rb
index 850a7889b56..1a928424c54 100644
--- a/app/controllers/user_badges_controller.rb
+++ b/app/controllers/user_badges_controller.rb
@@ -56,9 +56,9 @@ class UserBadgesController < ApplicationController
       params.permit(:badge_name)
       if params[:badge_name].nil?
         params.require(:badge_id)
-        badge = Badge.where(id: params[:badge_id]).first
+        badge = Badge.find_by(id: params[:badge_id])
       else
-        badge = Badge.where(name: params[:badge_name]).first
+        badge = Badge.find_by(name: params[:badge_name])
       end
       raise Discourse::NotFound.new if badge.blank?
 
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index f544efce950..d2fa2345cf1 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -312,7 +312,7 @@ class UsersController < ApplicationController
   # [LEGACY] avatars in quotes/oneboxes might still be pointing to this route
   # fixing it requires a rebake of all the posts
   def avatar
-    user = User.where(username_lower: params[:username].downcase).first
+    user = User.find_by(username_lower: params[:username].downcase)
     if user.present?
       size = determine_avatar_size(params[:size])
       url = user.avatar_template.gsub("{size}", size.to_s)
diff --git a/app/jobs/regular/close_topic.rb b/app/jobs/regular/close_topic.rb
index f1d50b49c82..61a27588cef 100644
--- a/app/jobs/regular/close_topic.rb
+++ b/app/jobs/regular/close_topic.rb
@@ -2,8 +2,8 @@ module Jobs
   class CloseTopic < Jobs::Base
 
     def execute(args)
-      if topic = Topic.where(id: args[:topic_id]).first
-        closer = User.where(id: args[:user_id]).first
+      if topic = Topic.find_by(id: args[:topic_id])
+        closer = User.find_by(id: args[:user_id])
         topic.auto_close(closer)
       end
     end
diff --git a/app/jobs/regular/crawl_topic_link.rb b/app/jobs/regular/crawl_topic_link.rb
index c8273473dba..04fc288ef35 100644
--- a/app/jobs/regular/crawl_topic_link.rb
+++ b/app/jobs/regular/crawl_topic_link.rb
@@ -83,7 +83,7 @@ module Jobs
     def execute(args)
       raise Discourse::InvalidParameters.new(:topic_link_id) unless args[:topic_link_id].present?
 
-      topic_link = TopicLink.where(id: args[:topic_link_id], internal: false, crawled_at: nil).first
+      topic_link = TopicLink.find_by(id: args[:topic_link_id], internal: false, crawled_at: nil)
       return if topic_link.blank?
 
       # Look for a topic embed for the URL. If it exists, use its title and don't crawl
diff --git a/app/jobs/regular/feature_topic_users.rb b/app/jobs/regular/feature_topic_users.rb
index 58aa4380bb2..6eabc024e2b 100644
--- a/app/jobs/regular/feature_topic_users.rb
+++ b/app/jobs/regular/feature_topic_users.rb
@@ -6,7 +6,7 @@ module Jobs
       topic_id = args[:topic_id]
       raise Discourse::InvalidParameters.new(:topic_id) unless topic_id.present?
 
-      topic = Topic.where(id: topic_id).first
+      topic = Topic.find_by(id: topic_id)
 
       # there are 3 cases here
       # 1. topic was atomically nuked, this should be skipped
diff --git a/app/jobs/regular/generate_avatars.rb b/app/jobs/regular/generate_avatars.rb
index dea5a195561..475adf3d3a8 100644
--- a/app/jobs/regular/generate_avatars.rb
+++ b/app/jobs/regular/generate_avatars.rb
@@ -11,8 +11,8 @@ module Jobs
       raise Discourse::InvalidParameters.new(:upload_id) if upload_id.blank?
       raise Discourse::InvalidParameters.new(:user_id) if user_id.blank?
 
-      upload = Upload.where(id: upload_id).first
-      user = User.where(id: user_id).first
+      upload = Upload.find_by(id: upload_id)
+      user = User.find_by(id: user_id)
       return if upload.nil? || user.nil?
 
       external_copy = Discourse.store.download(upload) if Discourse.store.external?
diff --git a/app/jobs/regular/invite_email.rb b/app/jobs/regular/invite_email.rb
index efaca7af4b8..f373134a2bd 100644
--- a/app/jobs/regular/invite_email.rb
+++ b/app/jobs/regular/invite_email.rb
@@ -8,7 +8,7 @@ module Jobs
     def execute(args)
       raise Discourse::InvalidParameters.new(:invite_id) unless args[:invite_id].present?
 
-      invite = Invite.where(id: args[:invite_id]).first
+      invite = Invite.find_by(id: args[:invite_id])
       message = InviteMailer.send_invite(invite)
       Email::Sender.new(message, :invite).send
     end
diff --git a/app/jobs/regular/notify_mailing_list_subscribers.rb b/app/jobs/regular/notify_mailing_list_subscribers.rb
index 8c7ba55227f..040ac906624 100644
--- a/app/jobs/regular/notify_mailing_list_subscribers.rb
+++ b/app/jobs/regular/notify_mailing_list_subscribers.rb
@@ -5,7 +5,7 @@ module Jobs
     def execute(args)
       post_id = args[:post_id]
       if post_id
-        post = Post.with_deleted.where(id: post_id).first
+        post = Post.with_deleted.find_by(id: post_id)
         return if post && post.trashed?
       end
 
diff --git a/app/jobs/regular/notify_moved_posts.rb b/app/jobs/regular/notify_moved_posts.rb
index 5818bab6631..da1300e86c1 100644
--- a/app/jobs/regular/notify_moved_posts.rb
+++ b/app/jobs/regular/notify_moved_posts.rb
@@ -10,7 +10,7 @@ module Jobs
       users_notified = Set.new
       posts = Post.where(id: args[:post_ids]).where('user_id <> ?', args[:moved_by_id]).includes(:user, :topic)
       if posts.present?
-        moved_by = User.where(id: args[:moved_by_id]).first
+        moved_by = User.find_by(id: args[:moved_by_id])
 
         posts.each do |p|
           unless users_notified.include?(p.user_id)
diff --git a/app/jobs/regular/process_post.rb b/app/jobs/regular/process_post.rb
index 42267fa73d6..e8753e7e167 100644
--- a/app/jobs/regular/process_post.rb
+++ b/app/jobs/regular/process_post.rb
@@ -6,7 +6,7 @@ module Jobs
   class ProcessPost < Jobs::Base
 
     def execute(args)
-      post = Post.where(id: args[:post_id]).first
+      post = Post.find_by(id: args[:post_id])
       # two levels of deletion
       return unless post.present? && post.topic.present?
 
diff --git a/app/jobs/regular/pull_hotlinked_images.rb b/app/jobs/regular/pull_hotlinked_images.rb
index df0ebab2a66..f8d67b8f32f 100644
--- a/app/jobs/regular/pull_hotlinked_images.rb
+++ b/app/jobs/regular/pull_hotlinked_images.rb
@@ -17,7 +17,7 @@ module Jobs
       post_id = args[:post_id]
       raise Discourse::InvalidParameters.new(:post_id) unless post_id.present?
 
-      post = Post.where(id: post_id).first
+      post = Post.find_by(id: post_id)
       return unless post.present?
 
       raw = post.raw.dup
diff --git a/app/jobs/regular/retrieve_topic.rb b/app/jobs/regular/retrieve_topic.rb
index dd3c79cf4d6..0b8e6dd2bb1 100644
--- a/app/jobs/regular/retrieve_topic.rb
+++ b/app/jobs/regular/retrieve_topic.rb
@@ -11,7 +11,7 @@ module Jobs
 
       user = nil
       if args[:user_id]
-        user = User.where(id: args[:user_id]).first
+        user = User.find_by(id: args[:user_id])
       end
 
       TopicRetriever.new(args[:embed_url], no_throttle: user.try(:staff?)).retrieve
diff --git a/app/jobs/regular/send_system_message.rb b/app/jobs/regular/send_system_message.rb
index e77169ec91d..d0dc41ec6f1 100644
--- a/app/jobs/regular/send_system_message.rb
+++ b/app/jobs/regular/send_system_message.rb
@@ -9,7 +9,7 @@ module Jobs
       raise Discourse::InvalidParameters.new(:user_id) unless args[:user_id].present?
       raise Discourse::InvalidParameters.new(:message_type) unless args[:message_type].present?
 
-      user = User.where(id: args[:user_id]).first
+      user = User.find_by(id: args[:user_id])
       return if user.blank?
 
       system_message = SystemMessage.new(user)
diff --git a/app/jobs/regular/update_top_redirection.rb b/app/jobs/regular/update_top_redirection.rb
index 8de2f03c024..97df9483d62 100644
--- a/app/jobs/regular/update_top_redirection.rb
+++ b/app/jobs/regular/update_top_redirection.rb
@@ -3,7 +3,7 @@ module Jobs
   class UpdateTopRedirection < Jobs::Base
 
     def execute(args)
-      user = User.where(id: args[:user_id]).first
+      user = User.find_by(id: args[:user_id])
       user.update_column(:last_redirected_to_top_at, args[:redirected_at])
     end
   end
diff --git a/app/jobs/regular/user_email.rb b/app/jobs/regular/user_email.rb
index 3e4408475c8..912019db7e3 100644
--- a/app/jobs/regular/user_email.rb
+++ b/app/jobs/regular/user_email.rb
@@ -14,7 +14,7 @@ module Jobs
       raise Discourse::InvalidParameters.new(:type) unless args[:type].present?
 
       # Find the user
-      @user = User.where(id: args[:user_id]).first
+      @user = User.find_by(id: args[:user_id])
       return skip(I18n.t("email_log.no_user", user_id: args[:user_id])) unless @user
       return skip(I18n.t("email_log.suspended_not_pm")) if @user.suspended? && args[:type] != :user_private_message
 
@@ -27,7 +27,7 @@ module Jobs
         # Don't email a user about a post when we've seen them recently.
         return skip(I18n.t('email_log.seen_recently')) if seen_recently
 
-        post = Post.where(id: args[:post_id]).first
+        post = Post.find_by(id: args[:post_id])
         return skip(I18n.t('email_log.post_not_found', post_id: args[:post_id])) unless post.present?
 
         email_args[:post] = post
@@ -36,13 +36,13 @@ module Jobs
       email_args[:email_token] = args[:email_token] if args[:email_token].present?
 
       notification = nil
-      notification = Notification.where(id: args[:notification_id]).first if args[:notification_id].present?
+      notification = Notification.find_by(id: args[:notification_id]) if args[:notification_id].present?
       if notification.present?
         # Don't email a user about a post when we've seen them recently.
         return skip(I18n.t('email_log.seen_recently')) if seen_recently && !@user.suspended?
 
         # Load the post if present
-        email_args[:post] ||= Post.where(id: notification.data_hash[:original_post_id].to_i).first
+        email_args[:post] ||= Post.find_by(id: notification.data_hash[:original_post_id].to_i)
         email_args[:post] ||= notification.post
         email_args[:notification] = notification
 
diff --git a/app/jobs/scheduled/poll_feed.rb b/app/jobs/scheduled/poll_feed.rb
index b9afd6a2207..fe88c920759 100644
--- a/app/jobs/scheduled/poll_feed.rb
+++ b/app/jobs/scheduled/poll_feed.rb
@@ -23,7 +23,7 @@ module Jobs
     end
 
     def poll_feed
-      user = User.where(username_lower: SiteSetting.embed_by_username.downcase).first
+      user = User.find_by(username_lower: SiteSetting.embed_by_username.downcase)
       return if user.blank?
 
       require 'simple-rss'
diff --git a/app/models/api_key.rb b/app/models/api_key.rb
index c1daf8ad085..dc6195baeb1 100644
--- a/app/models/api_key.rb
+++ b/app/models/api_key.rb
@@ -12,7 +12,7 @@ class ApiKey < ActiveRecord::Base
   end
 
   def self.create_master_key
-    api_key = ApiKey.where(user_id: nil).first
+    api_key = ApiKey.find_by(user_id: nil)
     if api_key.blank?
       api_key = ApiKey.create(key: SecureRandom.hex(32), created_by: Discourse.system_user)
     end
diff --git a/app/models/category.rb b/app/models/category.rb
index 2ef1a7501e1..2250093cf11 100644
--- a/app/models/category.rb
+++ b/app/models/category.rb
@@ -306,7 +306,7 @@ SQL
   end
 
   def self.find_by_email(email)
-    self.where(email_in: Email.downcase(email)).first
+    self.find_by(email_in: Email.downcase(email))
   end
 
   def has_children?
diff --git a/app/models/color_scheme.rb b/app/models/color_scheme.rb
index b1f9b000a28..1cf058bf454 100644
--- a/app/models/color_scheme.rb
+++ b/app/models/color_scheme.rb
@@ -9,7 +9,7 @@ class ColorScheme < ActiveRecord::Base
   after_destroy :destroy_versions
 
   def self.enabled
-    current_version.where(enabled: true).first || find(1)
+    current_version.find_by(enabled: true) || find(1)
   end
 
   def can_edit?
diff --git a/app/models/discourse_single_sign_on.rb b/app/models/discourse_single_sign_on.rb
index 75ecb889e20..1a7472f8c88 100644
--- a/app/models/discourse_single_sign_on.rb
+++ b/app/models/discourse_single_sign_on.rb
@@ -41,7 +41,7 @@ class DiscourseSingleSignOn < SingleSignOn
   end
 
   def lookup_or_create_user
-    sso_record = SingleSignOnRecord.where(external_id: external_id).first
+    sso_record = SingleSignOnRecord.find_by(external_id: external_id)
 
     if sso_record && user = sso_record.user
       sso_record.last_payload = unsigned_payload
@@ -75,7 +75,7 @@ class DiscourseSingleSignOn < SingleSignOn
   private
 
   def match_email_or_create_user
-    user = User.where(email: Email.downcase(email)).first
+    user = User.find_by(email: Email.downcase(email))
 
     user_params = {
         email: email,
diff --git a/app/models/draft_sequence.rb b/app/models/draft_sequence.rb
index e576dd1083a..b3548a1c14e 100644
--- a/app/models/draft_sequence.rb
+++ b/app/models/draft_sequence.rb
@@ -3,7 +3,7 @@ class DraftSequence < ActiveRecord::Base
     user_id = user
     user_id = user.id unless user.class == Fixnum
     h = { user_id: user_id, draft_key: key }
-    c = DraftSequence.where(h).first
+    c = DraftSequence.find_by(h)
     c ||= DraftSequence.new(h)
     c.sequence ||= 0
     c.sequence += 1
diff --git a/app/models/email_log.rb b/app/models/email_log.rb
index a187f6800ea..08a9e9615a4 100644
--- a/app/models/email_log.rb
+++ b/app/models/email_log.rb
@@ -19,7 +19,7 @@ class EmailLog < ActiveRecord::Base
   end
 
   def self.for(reply_key)
-    EmailLog.where(reply_key: reply_key).first
+    EmailLog.find_by(reply_key: reply_key)
   end
 
   def self.last_sent_email_address
diff --git a/app/models/group.rb b/app/models/group.rb
index e5cd9dc8a90..6bd93a534b4 100644
--- a/app/models/group.rb
+++ b/app/models/group.rb
@@ -155,9 +155,9 @@ class Group < ActiveRecord::Base
 
   def self.lookup_group(name)
     if id = AUTO_GROUPS[name]
-      Group.where(id: id).first
+      Group.find_by(id: id)
     else
-      unless group = Group.where(name: name).first
+      unless group = Group.find_by(name: name)
         raise ArgumentError, "unknown group"
       end
       group
diff --git a/app/models/incoming_link.rb b/app/models/incoming_link.rb
index 757bdeea483..21f8394e47a 100644
--- a/app/models/incoming_link.rb
+++ b/app/models/incoming_link.rb
@@ -13,7 +13,7 @@ class IncomingLink < ActiveRecord::Base
     user_id, host, referer = nil
 
     if request['u']
-      u = User.select(:id).where(username_lower: request['u'].downcase).first
+      u = User.select(:id).find_by(username_lower: request["u"].downcase)
       user_id = u.id if u
     end
 
diff --git a/app/models/invite.rb b/app/models/invite.rb
index 2ea756d7d5a..dd4f29a348f 100644
--- a/app/models/invite.rb
+++ b/app/models/invite.rb
@@ -24,7 +24,7 @@ class Invite < ActiveRecord::Base
   def user_doesnt_already_exist
     @email_already_exists = false
     return if email.blank?
-    u = User.where("email = ?", Email.downcase(email)).first
+    u = User.find_by("email = ?", Email.downcase(email))
     if u && u.id != self.user_id
       @email_already_exists = true
       errors.add(:email)
@@ -106,7 +106,7 @@ class Invite < ActiveRecord::Base
   end
 
   def self.invalidate_for_email(email)
-    i = Invite.where(email: Email.downcase(email)).first
+    i = Invite.find_by(email: Email.downcase(email))
     if i
       i.invalidated_at = Time.zone.now
       i.save
diff --git a/app/models/invite_redeemer.rb b/app/models/invite_redeemer.rb
index 05486b1778a..e9fe3d37b00 100644
--- a/app/models/invite_redeemer.rb
+++ b/app/models/invite_redeemer.rb
@@ -57,7 +57,7 @@ InviteRedeemer = Struct.new(:invite) do
   end
 
   def get_existing_user
-    User.where(email: invite.email).first
+    User.find_by(email: invite.email)
   end
 
 
diff --git a/app/models/notification.rb b/app/models/notification.rb
index a1a459e7ebd..93ba30ecd35 100644
--- a/app/models/notification.rb
+++ b/app/models/notification.rb
@@ -87,7 +87,7 @@ class Notification < ActiveRecord::Base
   def post
     return if topic_id.blank? || post_number.blank?
 
-    Post.where(topic_id: topic_id, post_number: post_number).first
+    Post.find_by(topic_id: topic_id, post_number: post_number)
   end
 
   def self.recent_report(user, count = nil)
diff --git a/app/models/optimized_image.rb b/app/models/optimized_image.rb
index 220751e1e54..a3dc6d3c38a 100644
--- a/app/models/optimized_image.rb
+++ b/app/models/optimized_image.rb
@@ -7,7 +7,7 @@ class OptimizedImage < ActiveRecord::Base
     return unless width > 0 && height > 0
 
     # do we already have that thumbnail?
-    thumbnail = where(upload_id: upload.id, width: width, height: height).first
+    thumbnail = find_by(upload_id: upload.id, width: width, height: height)
 
     # make sure the previous thumbnail has not failed
     if thumbnail && thumbnail.url.blank?
diff --git a/app/models/plugin_store.rb b/app/models/plugin_store.rb
index 640b61a2033..738d0971e3a 100644
--- a/app/models/plugin_store.rb
+++ b/app/models/plugin_store.rb
@@ -1,14 +1,14 @@
 # API to wrap up plugin store rows
 class PluginStore
   def self.get(plugin_name, key)
-    if row = PluginStoreRow.where(plugin_name: plugin_name, key: key).first
+    if row = PluginStoreRow.find_by(plugin_name: plugin_name, key: key)
       cast_value(row.type_name, row.value)
     end
   end
 
   def self.set(plugin_name, key, value)
     hash = {plugin_name: plugin_name, key: key}
-    row = PluginStoreRow.where(hash).first || row = PluginStoreRow.new(hash)
+    row = PluginStoreRow.find_by(hash) || row = PluginStoreRow.new(hash)
 
     row.type_name = determine_type(value)
     # nil are stored as nil
diff --git a/app/models/post.rb b/app/models/post.rb
index 0f0e0c84ddc..6a5081354f3 100644
--- a/app/models/post.rb
+++ b/app/models/post.rb
@@ -67,7 +67,7 @@ class Post < ActiveRecord::Base
   end
 
   def self.find_by_detail(key, value)
-    includes(:post_details).where(post_details: { key: key, value: value }).first
+    includes(:post_details).find_by(post_details: { key: key, value: value })
   end
 
   def add_detail(key, value, extra = nil)
@@ -250,17 +250,12 @@ class Post < ActiveRecord::Base
 
   def reply_to_post
     return if reply_to_post_number.blank?
-    @reply_to_post ||= Post.where("topic_id = :topic_id AND post_number = :post_number",
-                                  topic_id: topic_id,
-                                  post_number: reply_to_post_number).first
+    @reply_to_post ||= Post.find_by("topic_id = :topic_id AND post_number = :post_number", topic_id: topic_id, post_number: reply_to_post_number)
   end
 
   def reply_notification_target
     return if reply_to_post_number.blank?
-    Post.where("topic_id = :topic_id AND post_number = :post_number AND user_id <> :user_id",
-                topic_id: topic_id,
-                post_number: reply_to_post_number,
-                user_id: user_id).first.try(:user)
+    Post.find_by("topic_id = :topic_id AND post_number = :post_number AND user_id <> :user_id", topic_id: topic_id, post_number: reply_to_post_number, user_id: user_id).try(:user)
   end
 
   def self.excerpt(cooked, maxlength = nil, options = {})
@@ -401,7 +396,7 @@ class Post < ActiveRecord::Base
 
     # Create a reply relationship between quoted posts and this new post
     self.quoted_post_numbers.each do |p|
-      post = Post.where(topic_id: topic_id, post_number: p).first
+      post = Post.find_by(topic_id: topic_id, post_number: p)
       create_reply_relationship_with(post)
     end
   end
@@ -442,7 +437,7 @@ class Post < ActiveRecord::Base
 
   def revert_to(number)
     return if number >= version
-    post_revision = PostRevision.where(post_id: id, number: number + 1).first
+    post_revision = PostRevision.find_by(post_id: id, number: (number + 1))
     post_revision.modifications.each do |attribute, change|
       attribute = "version" if attribute == "cached_version"
       write_attribute(attribute, change[0])
@@ -495,7 +490,7 @@ class Post < ActiveRecord::Base
   end
 
   def update_revision
-    revision = PostRevision.where(post_id: id, number: version).first
+    revision = PostRevision.find_by(post_id: id, number: version)
     return unless revision
     revision.user_id = last_editor_id
     modifications = changes.extract!(:raw, :cooked, :edit_reason)
diff --git a/app/models/post_action.rb b/app/models/post_action.rb
index 261b3dd5821..eb317f9f11a 100644
--- a/app/models/post_action.rb
+++ b/app/models/post_action.rb
@@ -143,9 +143,7 @@ class PostAction < ActiveRecord::Base
   end
 
   def self.remove_act(user, post, post_action_type_id)
-    if action = where(post_id: post.id,
-                      user_id: user.id,
-                      post_action_type_id: post_action_type_id).first
+    if action = find_by(post_id: post.id, user_id: user.id, post_action_type_id: post_action_type_id)
       action.remove_act!(user)
     end
   end
@@ -319,7 +317,7 @@ class PostAction < ActiveRecord::Base
   end
 
   def self.post_action_type_for_post(post_id)
-    post_action = PostAction.where(defer: nil, post_id: post_id, post_action_type_id: PostActionType.flag_types.values, deleted_at: nil).first
+    post_action = PostAction.find_by(defer: nil, post_id: post_id, post_action_type_id: PostActionType.flag_types.values, deleted_at: nil)
     PostActionType.types[post_action.post_action_type_id]
   end
 
diff --git a/app/models/post_revision.rb b/app/models/post_revision.rb
index 990705289ee..9e4053abc43 100644
--- a/app/models/post_revision.rb
+++ b/app/models/post_revision.rb
@@ -47,8 +47,8 @@ class PostRevision < ActiveRecord::Base
     return if prev == cur
 
     {
-        previous_user: User.where(id: prev).first,
-        current_user: User.where(id: cur).first
+        previous_user: User.find_by(id: prev),
+        current_user: User.find_by(id: cur)
     }
   end
 
diff --git a/app/models/screened_email.rb b/app/models/screened_email.rb
index 99c940b03a6..0dd2cc1858d 100644
--- a/app/models/screened_email.rb
+++ b/app/models/screened_email.rb
@@ -17,7 +17,7 @@ class ScreenedEmail < ActiveRecord::Base
   end
 
   def self.should_block?(email)
-    screened_email = ScreenedEmail.where(email: email).first
+    screened_email = ScreenedEmail.find_by(email: email)
     screened_email.record_match! if screened_email
     screened_email && screened_email.action_type == actions[:block]
   end
diff --git a/app/models/screened_ip_address.rb b/app/models/screened_ip_address.rb
index f750865edfa..c5f80fefd02 100644
--- a/app/models/screened_ip_address.rb
+++ b/app/models/screened_ip_address.rb
@@ -65,7 +65,7 @@ class ScreenedIpAddress < ActiveRecord::Base
     #
     #   http://www.postgresql.org/docs/9.1/static/datatype-net-types.html
     #   http://www.postgresql.org/docs/9.1/static/functions-net.html
-    where("'#{ip_address.to_s}' <<= ip_address").first
+    find_by("'#{ip_address.to_s}' <<= ip_address")
   end
 
   def self.should_block?(ip_address)
diff --git a/app/models/search_observer.rb b/app/models/search_observer.rb
index abc7d03f696..883aaa9e858 100644
--- a/app/models/search_observer.rb
+++ b/app/models/search_observer.rb
@@ -50,7 +50,7 @@ class SearchObserver < ActiveRecord::Observer
 
     if obj.class == Topic && obj.title_changed?
       if obj.posts
-        post = obj.posts.where(post_number: 1).first
+        post = obj.posts.find_by(post_number: 1)
         if post
           category_name = obj.category.name if obj.category
           SearchObserver.update_posts_index(post.id, post.cooked, obj.title, category_name)
diff --git a/app/models/site_customization.rb b/app/models/site_customization.rb
index 6e8fa1bfeb6..eac472b8038 100644
--- a/app/models/site_customization.rb
+++ b/app/models/site_customization.rb
@@ -99,7 +99,7 @@ class SiteCustomization < ActiveRecord::Base
     return preview_style if preview_style
 
     @lock.synchronize do
-      style = where(enabled: true).first
+      style = find_by(enabled: true)
       if style
         @cache[enabled_key] = style.key
       else
@@ -141,7 +141,7 @@ class SiteCustomization < ActiveRecord::Base
     return style if style
 
     @lock.synchronize do
-      style = where(key: key).first
+      style = find_by(key: key)
       style.ensure_stylesheets_on_disk! if style
       @cache[key] = style
     end
diff --git a/app/models/topic.rb b/app/models/topic.rb
index 9360b98477d..0b6efad65f7 100644
--- a/app/models/topic.rb
+++ b/app/models/topic.rb
@@ -447,7 +447,7 @@ class Topic < ActiveRecord::Base
   end
 
   def changed_to_category(cat)
-    return true if cat.blank? || Category.where(topic_id: id).first.present?
+    return true if cat.blank? || Category.find_by(topic_id: id).present?
 
     Topic.transaction do
       old_category = category
@@ -502,9 +502,9 @@ class Topic < ActiveRecord::Base
   def change_category(name)
     # If the category name is blank, reset the attribute
     if name.blank?
-      cat = Category.where(id: SiteSetting.uncategorized_category_id).first
+      cat = Category.find_by(id: SiteSetting.uncategorized_category_id)
     else
-      cat = Category.where(name: name).first
+      cat = Category.find_by(name: name)
     end
 
     return true if cat == category
@@ -514,9 +514,9 @@ class Topic < ActiveRecord::Base
 
 
   def remove_allowed_user(username)
-    user = User.where(username: username).first
+    user = User.find_by(username: username)
     if user
-      topic_user = topic_allowed_users.where(user_id: user.id).first
+      topic_user = topic_allowed_users.find_by(user_id: user.id)
       if topic_user
         topic_user.destroy
       else
@@ -559,7 +559,7 @@ class Topic < ActiveRecord::Base
   end
 
   def grant_permission_to_user(lower_email)
-    user = User.where(email: lower_email).first
+    user = User.find_by(email: lower_email)
     topic_allowed_users.create!(user_id: user.id)
   end
 
diff --git a/app/models/topic_embed.rb b/app/models/topic_embed.rb
index 0c9c918f6c5..1cd1fddfb01 100644
--- a/app/models/topic_embed.rb
+++ b/app/models/topic_embed.rb
@@ -24,7 +24,7 @@ class TopicEmbed < ActiveRecord::Base
 
     url = normalize_url(url)
 
-    embed = TopicEmbed.where("lower(embed_url) = ?", url).first
+    embed = TopicEmbed.find_by("lower(embed_url) = ?", url)
     content_sha1 = Digest::SHA1.hexdigest(contents)
     post = nil
 
diff --git a/app/models/topic_link.rb b/app/models/topic_link.rb
index 08bd0bfd1cc..cd8a106d4a2 100644
--- a/app/models/topic_link.rb
+++ b/app/models/topic_link.rb
@@ -123,7 +123,7 @@ class TopicLink < ActiveRecord::Base
             post_number = route[:post_number] || 1
 
             # Store the canonical URL
-            topic = Topic.where(id: topic_id).first
+            topic = Topic.find_by(id: topic_id)
 
             if topic.present?
               url = "#{Discourse.base_url}#{topic.relative_url}"
@@ -137,7 +137,7 @@ class TopicLink < ActiveRecord::Base
 
           reflected_post = nil
           if post_number && topic_id
-            reflected_post = Post.where(topic_id: topic_id, post_number: post_number.to_i).first
+            reflected_post = Post.find_by(topic_id: topic_id, post_number: post_number.to_i)
           end
 
           added_urls << url
@@ -152,7 +152,7 @@ class TopicLink < ActiveRecord::Base
 
           # Create the reflection if we can
           if topic_id.present?
-            topic = Topic.where(id: topic_id).first
+            topic = Topic.find_by(id: topic_id)
 
             if topic && post.topic && post.topic.archetype != 'private_message' && topic.archetype != 'private_message'
 
diff --git a/app/models/topic_link_click.rb b/app/models/topic_link_click.rb
index 575b6a1e882..0e5f2144bff 100644
--- a/app/models/topic_link_click.rb
+++ b/app/models/topic_link_click.rb
@@ -33,7 +33,7 @@ class TopicLinkClick < ActiveRecord::Base
 
       # If we have it somewhere else on the site, just allow the redirect. This is
       # likely due to a onebox of another topic.
-      link = TopicLink.where(url: args[:url]).first
+      link = TopicLink.find_by(url: args[:url])
       return link.present? ? link.url : nil
     end
 
diff --git a/app/models/topic_notifier.rb b/app/models/topic_notifier.rb
index 6cdaab4ee84..ee25a159244 100644
--- a/app/models/topic_notifier.rb
+++ b/app/models/topic_notifier.rb
@@ -24,7 +24,7 @@ class TopicNotifier
   end
 
   def muted?(user_id)
-    tu = @topic.topic_users.where(user_id: user_id).first
+    tu = @topic.topic_users.find_by(user_id: user_id)
     tu && tu.notification_level == levels[:muted]
   end
 
diff --git a/app/models/topic_user.rb b/app/models/topic_user.rb
index 4053dd78af3..dbe5b3313b5 100644
--- a/app/models/topic_user.rb
+++ b/app/models/topic_user.rb
@@ -99,7 +99,7 @@ class TopicUser < ActiveRecord::Base
 
         if rows == 0
           now = DateTime.now
-          auto_track_after = User.select(:auto_track_topics_after_msecs).where(id: user_id).first.auto_track_topics_after_msecs
+          auto_track_after = User.select(:auto_track_topics_after_msecs).find_by(id: user_id).auto_track_topics_after_msecs
           auto_track_after ||= SiteSetting.auto_track_topics_after
 
           if auto_track_after >= 0 && auto_track_after <= (attrs[:total_msecs_viewed] || 0)
diff --git a/app/models/upload.rb b/app/models/upload.rb
index fc630df618a..ea5581af949 100644
--- a/app/models/upload.rb
+++ b/app/models/upload.rb
@@ -17,7 +17,7 @@ class Upload < ActiveRecord::Base
   validates_with ::Validators::UploadValidator
 
   def thumbnail(width = self.width, height = self.height)
-    optimized_images.where(width: width, height: height).first
+    optimized_images.find_by(width: width, height: height)
   end
 
   def has_thumbnail?(width, height)
@@ -53,7 +53,7 @@ class Upload < ActiveRecord::Base
     # compute the sha
     sha1 = Digest::SHA1.file(file).hexdigest
     # check if the file has already been uploaded
-    upload = Upload.where(sha1: sha1).first
+    upload = Upload.find_by(sha1: sha1)
     # delete the previously uploaded file if there's been an error
     if upload && upload.url.blank?
       upload.destroy
@@ -112,7 +112,7 @@ class Upload < ActiveRecord::Base
   def self.get_from_url(url)
     # we store relative urls, so we need to remove any host/cdn
     url = url.gsub(/^#{Discourse.asset_host}/i, "") if Discourse.asset_host.present?
-    Upload.where(url: url).first if Discourse.store.has_been_uploaded?(url)
+    Upload.find_by(url: url) if Discourse.store.has_been_uploaded?(url)
   end
 
 end
diff --git a/app/models/user.rb b/app/models/user.rb
index c9b60a9bc2f..30daf56752b 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -138,7 +138,7 @@ class User < ActiveRecord::Base
   def self.find_by_temporary_key(key)
     user_id = $redis.get("temporary_key:#{key}")
     if user_id.present?
-      where(id: user_id.to_i).first
+      find_by(id: user_id.to_i)
     end
   end
 
@@ -151,11 +151,11 @@ class User < ActiveRecord::Base
   end
 
   def self.find_by_email(email)
-    where(email: Email.downcase(email)).first
+    find_by(email: Email.downcase(email))
   end
 
   def self.find_by_username(username)
-    where(username_lower: username.downcase).first
+    find_by(username_lower: username.downcase)
   end
 
 
@@ -296,7 +296,7 @@ class User < ActiveRecord::Base
   end
 
   def visit_record_for(date)
-    user_visits.where(visited_at: date).first
+    user_visits.find_by(visited_at: date)
   end
 
   def update_visit_record!(date)
@@ -676,7 +676,7 @@ class User < ActiveRecord::Base
   def username_validator
     username_format_validator || begin
       lower = username.downcase
-      existing = User.where(username_lower: lower).first
+      existing = User.find_by(username_lower: lower)
       if username_changed? && existing && existing.id != self.id
         errors.add(:username, I18n.t(:'user.username.unique'))
       end
diff --git a/app/models/user_action.rb b/app/models/user_action.rb
index 9ed54714a4d..0c19f8c93ee 100644
--- a/app/models/user_action.rb
+++ b/app/models/user_action.rb
@@ -155,7 +155,9 @@ LEFT JOIN categories c on c.id = t.category_id
         # TODO there are conditions when this is called and user_id was already rolled back and is invalid.
 
         # protect against dupes, for some reason this is failing in some cases
-        action = self.where(hash.select{|k,v| required_parameters.include?(k)}).first
+        action = self.find_by(hash.select do |k, v|
+  required_parameters.include?(k)
+end)
         return action if action
 
         action = self.new(hash)
@@ -168,7 +170,7 @@ LEFT JOIN categories c on c.id = t.category_id
         user_id = hash[:user_id]
         update_like_count(user_id, hash[:action_type], 1)
 
-        topic = Topic.includes(:category).where(id: hash[:target_topic_id]).first
+        topic = Topic.includes(:category).find_by(id: hash[:target_topic_id])
 
         # move into Topic perhaps
         group_ids = nil
@@ -194,7 +196,7 @@ LEFT JOIN categories c on c.id = t.category_id
 
   def self.remove_action!(hash)
     require_parameters(hash, :action_type, :user_id, :acting_user_id, :target_topic_id, :target_post_id)
-    if action = UserAction.where(hash.except(:created_at)).first
+    if action = UserAction.find_by(hash.except(:created_at))
       action.destroy
       MessageBus.publish("/user/#{hash[:user_id]}", {user_action_id: action.id, remove: true})
     end
diff --git a/app/services/post_alerter.rb b/app/services/post_alerter.rb
index bc12a9fd46e..6c44b706df9 100644
--- a/app/services/post_alerter.rb
+++ b/app/services/post_alerter.rb
@@ -137,7 +137,7 @@ class PostAlerter
   # Returns a list of users who were quoted in the post
   def extract_quoted_users(post)
     post.raw.scan(/\[quote=\"([^,]+),.+\"\]/).uniq.map do |m|
-      User.where("username_lower = :username and id != :id", username: m.first.strip.downcase, id: post.user_id).first
+      User.find_by("username_lower = :username and id != :id", username: m.first.strip.downcase, id: post.user_id)
     end.compact
   end
 
diff --git a/app/services/user_destroyer.rb b/app/services/user_destroyer.rb
index fca5bdfbcdb..f2d5505cedd 100644
--- a/app/services/user_destroyer.rb
+++ b/app/services/user_destroyer.rb
@@ -53,7 +53,7 @@ class UserDestroyer
           categories.each do |c|
             c.user_id = Discourse.system_user.id
             c.save!
-            if topic = Topic.with_deleted.where(id: c.topic_id).first
+            if topic = Topic.with_deleted.find_by(id: c.topic_id)
               topic.try(:recover!)
               topic.user_id = Discourse.system_user.id
               topic.save!
diff --git a/db/fixtures/005_users.rb b/db/fixtures/005_users.rb
index d71aae88d37..326a13d7e57 100644
--- a/db/fixtures/005_users.rb
+++ b/db/fixtures/005_users.rb
@@ -1,7 +1,7 @@
 # kind of odd, but we need it, we also need to nuke usage of User from inside migrations
 #  very poor form
 User.reset_column_information
-user = User.where("id <> -1 and username_lower = 'system'").first
+user = User.find_by("id <> -1 and username_lower = 'system'")
 if user
   user.username = UserNameSuggester.suggest("system")
   user.save
diff --git a/db/fixtures/500_lounge_category.rb b/db/fixtures/500_lounge_category.rb
index 469a29a4a13..83d8eb5cf24 100644
--- a/db/fixtures/500_lounge_category.rb
+++ b/db/fixtures/500_lounge_category.rb
@@ -1,5 +1,5 @@
 unless Rails.env.test?
-  lounge = Category.where(id: SiteSetting.lounge_category_id).first
+  lounge = Category.find_by(id: SiteSetting.lounge_category_id)
   if lounge and !lounge.group_ids.include?(Group[:trust_level_3].id)
 
     # The category for users with trust level 3 has been created.
diff --git a/db/fixtures/501_meta_category.rb b/db/fixtures/501_meta_category.rb
index a0827c60239..9996b2abc81 100644
--- a/db/fixtures/501_meta_category.rb
+++ b/db/fixtures/501_meta_category.rb
@@ -1,5 +1,5 @@
 unless Rails.env.test?
-  meta = Category.where(id: SiteSetting.meta_category_id).first
+  meta = Category.find_by(id: SiteSetting.meta_category_id)
   if meta && !meta.topic_id
 
     Category.transaction do
diff --git a/db/fixtures/502_staff_category.rb b/db/fixtures/502_staff_category.rb
index 116a13dfba3..f1b62c1bf2c 100644
--- a/db/fixtures/502_staff_category.rb
+++ b/db/fixtures/502_staff_category.rb
@@ -1,5 +1,5 @@
 unless Rails.env.test?
-  staff = Category.where(id: SiteSetting.staff_category_id).first
+  staff = Category.find_by(id: SiteSetting.staff_category_id)
   if staff and !staff.group_ids.include?(Group[:staff].id)
 
     # Add permissions and a description to the Staff category.
diff --git a/db/fixtures/999_topics.rb b/db/fixtures/999_topics.rb
index d3d148e7aa3..d7363c1c3dd 100644
--- a/db/fixtures/999_topics.rb
+++ b/db/fixtures/999_topics.rb
@@ -5,7 +5,7 @@ Post.reset_column_information
 if Topic.where('id NOT IN (SELECT topic_id from categories where topic_id is not null)').count == 0 && !Rails.env.test?
   puts "Seeding welcome topics"
 
-  staff = Category.where(id: SiteSetting.staff_category_id).first
+  staff = Category.find_by(id: SiteSetting.staff_category_id)
   welcome = File.read(Rails.root + 'docs/ADMIN-QUICK-START-GUIDE.md')
   PostCreator.create(Discourse.system_user, raw: welcome, title: "READ ME FIRST: Admin Quick Start Guide", skip_validations: true, category: staff ? staff.name : nil)
   PostCreator.create(Discourse.system_user, raw: I18n.t('assets_topic_body'), title: "Assets for the forum design", skip_validations: true, category: staff ? staff.name : nil)
diff --git a/db/migrate/20121204183855_fix_link_post_id.rb b/db/migrate/20121204183855_fix_link_post_id.rb
index f61a0acdc10..4b03b963275 100644
--- a/db/migrate/20121204183855_fix_link_post_id.rb
+++ b/db/migrate/20121204183855_fix_link_post_id.rb
@@ -8,7 +8,7 @@ class FixLinkPostId < ActiveRecord::Migration
         parsed = URI.parse(tl.url)
         route = Rails.application.routes.recognize_path(parsed.path)
         if route[:topic_id].present?
-          post = Post.where(topic_id: route[:topic_id], post_number: route[:post_number] || 1).first
+          post = Post.find_by(topic_id: route[:topic_id], post_number: (route[:post_number] || 1))
           tl.update_column(:link_post_id, post.id) if post.present?
         end
 
diff --git a/db/migrate/20140211230222_move_cas_settings.rb b/db/migrate/20140211230222_move_cas_settings.rb
index dc21545419c..0de988fbfad 100644
--- a/db/migrate/20140211230222_move_cas_settings.rb
+++ b/db/migrate/20140211230222_move_cas_settings.rb
@@ -2,8 +2,8 @@ class MoveCasSettings < ActiveRecord::Migration
   def change
     #As part of removing the build in CAS authentication we should
     #convert the data over to be used by the plugin.
-    cas_hostname = SiteSetting.where(name: 'cas_hostname').first
-    cas_sso_hostname = SiteSetting.where(name: 'cas_sso_hostname').first
+    cas_hostname = SiteSetting.find_by(name: "cas_hostname")
+    cas_sso_hostname = SiteSetting.find_by(name: "cas_sso_hostname")
     if cas_hostname  && ! cas_sso_hostname
       #convert the setting over for use by the plugin
       cas_hostname.update_attribute(:name, 'cas_sso_hostname')
@@ -13,8 +13,8 @@ class MoveCasSettings < ActiveRecord::Migration
       cas_hostname.destroy
     end
 
-    cas_domainname = SiteSetting.where(name: 'cas_domainname').first
-    cas_sso_email_domain = SiteSetting.where(name: 'cas_sso_email_domain').first
+    cas_domainname = SiteSetting.find_by(name: "cas_domainname")
+    cas_sso_email_domain = SiteSetting.find_by(name: "cas_sso_email_domain")
     if cas_domainname  && ! cas_sso_email_domain
       #convert the setting over for use by the plugin
       cas_domainname.update_attribute(:name, 'cas_sso_email_domain')
@@ -24,7 +24,7 @@ class MoveCasSettings < ActiveRecord::Migration
       cas_domainname.destroy
     end
 
-    cas_logins = SiteSetting.where(name: 'cas_logins').first
+    cas_logins = SiteSetting.find_by(name: "cas_logins")
     if cas_logins
       cas_logins.destroy
     end
diff --git a/lib/auth/default_current_user_provider.rb b/lib/auth/default_current_user_provider.rb
index 6752b45b099..cce96d54850 100644
--- a/lib/auth/default_current_user_provider.rb
+++ b/lib/auth/default_current_user_provider.rb
@@ -24,7 +24,7 @@ class Auth::DefaultCurrentUserProvider
     current_user = nil
 
     if auth_token && auth_token.length == 32
-      current_user = User.where(auth_token: auth_token).first
+      current_user = User.find_by(auth_token: auth_token)
     end
 
     if current_user && (current_user.suspended? || !current_user.active)
@@ -53,7 +53,7 @@ class Auth::DefaultCurrentUserProvider
             raise Discourse::InvalidAccess.new if api_username && (api_key.user.username_lower != api_username.downcase)
             current_user = api_key.user
           elsif api_username
-            current_user = User.where(username_lower: api_username.downcase).first
+            current_user = User.find_by(username_lower: api_username.downcase)
           end
 
         end
diff --git a/lib/auth/facebook_authenticator.rb b/lib/auth/facebook_authenticator.rb
index 05b6c7b4baa..f2f85c70d04 100644
--- a/lib/auth/facebook_authenticator.rb
+++ b/lib/auth/facebook_authenticator.rb
@@ -17,10 +17,10 @@ class Auth::FacebookAuthenticator < Auth::Authenticator
 
     result.extra_data = facebook_hash
 
-    user_info = FacebookUserInfo.where(facebook_user_id: facebook_hash[:facebook_user_id]).first
+    user_info = FacebookUserInfo.find_by(facebook_user_id: facebook_hash[:facebook_user_id])
     result.user = user_info.try(:user)
 
-    if !result.user && !email.blank? && result.user = User.where(email: Email.downcase(email)).first
+    if !result.user && !email.blank? && result.user = User.find_by(email: Email.downcase(email))
       FacebookUserInfo.create({user_id: result.user.id}.merge(facebook_hash))
     end
 
diff --git a/lib/auth/github_authenticator.rb b/lib/auth/github_authenticator.rb
index 50b63c27bf9..5ca16a551af 100644
--- a/lib/auth/github_authenticator.rb
+++ b/lib/auth/github_authenticator.rb
@@ -19,7 +19,7 @@ class Auth::GithubAuthenticator < Auth::Authenticator
       github_screen_name: screen_name,
     }
 
-    user_info = GithubUserInfo.where(github_user_id: github_user_id).first
+    user_info = GithubUserInfo.find_by(github_user_id: github_user_id)
 
     if user_info
       user = user_info.user
diff --git a/lib/auth/oauth2_authenticator.rb b/lib/auth/oauth2_authenticator.rb
index 089f006f7ab..5484a19f5fb 100644
--- a/lib/auth/oauth2_authenticator.rb
+++ b/lib/auth/oauth2_authenticator.rb
@@ -20,7 +20,7 @@ class Auth::OAuth2Authenticator < Auth::Authenticator
     result.email = email = data[:email]
     result.name = name = data[:name]
 
-    oauth2_user_info = Oauth2UserInfo.where(uid: oauth2_uid, provider: oauth2_provider).first
+    oauth2_user_info = Oauth2UserInfo.find_by(uid: oauth2_uid, provider: oauth2_provider)
 
     if !oauth2_user_info && @opts[:trusted] && user = User.find_by_email(email)
       oauth2_user_info = Oauth2UserInfo.create(uid: oauth2_uid,
diff --git a/lib/auth/twitter_authenticator.rb b/lib/auth/twitter_authenticator.rb
index 43578da201d..3abe9edc522 100644
--- a/lib/auth/twitter_authenticator.rb
+++ b/lib/auth/twitter_authenticator.rb
@@ -21,7 +21,7 @@ class Auth::TwitterAuthenticator < Auth::Authenticator
       twitter_screen_name: screen_name
     }
 
-    user_info = TwitterUserInfo.where(twitter_user_id: twitter_user_id).first
+    user_info = TwitterUserInfo.find_by(twitter_user_id: twitter_user_id)
 
     result.user = user_info.try(:user)
 
diff --git a/lib/composer_messages_finder.rb b/lib/composer_messages_finder.rb
index 8f29eab0721..99d30a41bd5 100644
--- a/lib/composer_messages_finder.rb
+++ b/lib/composer_messages_finder.rb
@@ -101,7 +101,7 @@ class ComposerMessagesFinder
                   (@user.post_count >= SiteSetting.educate_until_posts) &&
                   !UserHistory.exists_for_user?(@user, :notified_about_dominating_topic, topic_id: @details[:topic_id])
 
-    topic = Topic.where(id: @details[:topic_id]).first
+    topic = Topic.find_by(id: @details[:topic_id])
     return if topic.blank? ||
               topic.user_id == @user.id ||
               topic.posts_count < SiteSetting.summary_posts_required ||
@@ -127,7 +127,7 @@ class ComposerMessagesFinder
   def check_reviving_old_topic
     return unless @details[:topic_id]
 
-    topic = Topic.where(id: @details[:topic_id]).first
+    topic = Topic.find_by(id: @details[:topic_id])
 
     return unless replying?
 
diff --git a/lib/discourse.rb b/lib/discourse.rb
index 835636aba0f..4fc54a04cf5 100644
--- a/lib/discourse.rb
+++ b/lib/discourse.rb
@@ -197,12 +197,12 @@ module Discourse
 
   # Either returns the site_contact_username user or the first admin.
   def self.site_contact_user
-    user = User.where(username_lower: SiteSetting.site_contact_username.downcase).first if SiteSetting.site_contact_username.present?
+    user = User.find_by(username_lower: SiteSetting.site_contact_username.downcase) if SiteSetting.site_contact_username.present?
     user ||= User.admins.real.order(:id).first
   end
 
   def self.system_user
-    User.where(id: -1).first
+    User.find_by(id: -1)
   end
 
   def self.store
diff --git a/lib/export/exporter.rb b/lib/export/exporter.rb
index 96bdaeeb67b..06a230859f9 100644
--- a/lib/export/exporter.rb
+++ b/lib/export/exporter.rb
@@ -65,7 +65,7 @@ module Export
     end
 
     def ensure_we_have_a_user
-      @user = User.where(id: @user_id).first
+      @user = User.find_by(id: @user_id)
       raise Discourse::InvalidParameters.new(:user_id) unless @user
     end
 
diff --git a/lib/import/importer.rb b/lib/import/importer.rb
index 54f2ab65010..bbb4961d719 100644
--- a/lib/import/importer.rb
+++ b/lib/import/importer.rb
@@ -79,7 +79,7 @@ module Import
     end
 
     def ensure_we_have_a_user
-      user = User.where(id: @user_id).first
+      user = User.find_by(id: @user_id)
       raise Discourse::InvalidParameters.new(:user_id) unless user
       # keep some user data around to check them against the newly restored database
       @user_info = { id: user.id, username: user.username, email: user.email }
@@ -280,7 +280,7 @@ module Import
     end
 
     def notify_user
-      if user = User.where(email: @user_info[:email]).first
+      if user = User.find_by(email: @user_info[:email])
         log "Notifying '#{user.username}' of the end of the restore..."
         # NOTE: will only notify if user != Discourse.site_contact_user
         if @success
diff --git a/lib/onebox/engine/discourse_local_onebox.rb b/lib/onebox/engine/discourse_local_onebox.rb
index 311891e0ec0..153a14b506d 100644
--- a/lib/onebox/engine/discourse_local_onebox.rb
+++ b/lib/onebox/engine/discourse_local_onebox.rb
@@ -23,7 +23,7 @@ module Onebox
           linked = "<a href='#{@url}'>#{@url}</a>"
           if route[:post_number].present? && route[:post_number].to_i > 1
             # Post Link
-            post = Post.where(topic_id: route[:topic_id], post_number: route[:post_number].to_i).first
+            post = Post.find_by(topic_id: route[:topic_id], post_number: route[:post_number].to_i)
             return linked unless post
             return linked if post.hidden
             return linked unless Guardian.new.can_see?(post)
diff --git a/lib/post_creator.rb b/lib/post_creator.rb
index 4dacf457b79..5e1f43855ad 100644
--- a/lib/post_creator.rb
+++ b/lib/post_creator.rb
@@ -105,7 +105,7 @@ class PostCreator
   def self.set_reply_user_id(post)
     return unless post.reply_to_post_number.present?
 
-    post.reply_to_user_id ||= Post.select(:user_id).where(topic_id: post.topic_id, post_number: post.reply_to_post_number).first.try(:user_id)
+    post.reply_to_user_id ||= Post.select(:user_id).find_by(topic_id: post.topic_id, post_number: post.reply_to_post_number).try(:user_id)
   end
 
   protected
@@ -148,15 +148,11 @@ class PostCreator
   def clear_possible_flags(topic)
     # at this point we know the topic is a PM and has been replied to ... check if we need to clear any flags
     #
-    first_post = Post.select(:id).where(topic_id: topic.id).where('post_number = 1').first
+    first_post = Post.select(:id).where(topic_id: topic.id).find_by("post_number = 1")
     post_action = nil
 
     if first_post
-      post_action = PostAction.where(
-        related_post_id: first_post.id,
-        deleted_at: nil,
-        post_action_type_id: PostActionType.types[:notify_moderators]
-      ).first
+      post_action = PostAction.find_by(related_post_id: first_post.id, deleted_at: nil, post_action_type_id: PostActionType.types[:notify_moderators])
     end
 
     if post_action
@@ -179,7 +175,7 @@ class PostCreator
         raise ex
       end
     else
-      topic = Topic.where(id: @opts[:topic_id]).first
+      topic = Topic.find_by(id: @opts[:topic_id])
       guardian.ensure_can_create!(Post, topic)
     end
     @topic = topic
diff --git a/lib/post_revisor.rb b/lib/post_revisor.rb
index edb9a1c296c..9bbd4444c17 100644
--- a/lib/post_revisor.rb
+++ b/lib/post_revisor.rb
@@ -116,7 +116,7 @@ class PostRevisor
     return unless @post.post_number == 1
 
     # Is there a category with our topic id?
-    category = Category.where(topic_id: @post.topic_id).first
+    category = Category.find_by(topic_id: @post.topic_id)
     return unless category.present?
 
     # If found, update its description
diff --git a/lib/pretty_text.rb b/lib/pretty_text.rb
index c24a3abc411..0828a2ff012 100644
--- a/lib/pretty_text.rb
+++ b/lib/pretty_text.rb
@@ -23,7 +23,7 @@ module PrettyText
     def avatar_template(username)
       return "" unless username
 
-      user = User.where(username_lower: username.downcase).first
+      user = User.find_by(username_lower: username.downcase)
       user.avatar_template if user.present?
     end
 
diff --git a/lib/search.rb b/lib/search.rb
index 8c45f9eed4d..97d8532984b 100644
--- a/lib/search.rb
+++ b/lib/search.rb
@@ -109,7 +109,7 @@ class Search
 
     # If we're searching for a single topic
     def single_topic(id)
-      topic = Topic.where(id: id).first
+      topic = Topic.find_by(id: id)
       return nil unless @guardian.can_see?(topic)
 
       @results.add_result(SearchResult.from_topic(topic))
diff --git a/lib/site_content_class_methods.rb b/lib/site_content_class_methods.rb
index faa493e51e2..87890bc22a4 100644
--- a/lib/site_content_class_methods.rb
+++ b/lib/site_content_class_methods.rb
@@ -20,7 +20,7 @@ module SiteContentClassMethods
     replacements = {site_name: SiteSetting.title}.merge!(replacements)
     replacements = SiteSetting.settings_hash.merge!(replacements)
 
-    site_content = SiteContent.select(:content).where(content_type: content_type).first
+    site_content = SiteContent.select(:content).find_by(content_type: content_type)
 
     result = ""
     if site_content.blank?
@@ -39,7 +39,7 @@ module SiteContentClassMethods
 
 
   def find_or_new(content_type)
-    site_content = SiteContent.where(content_type: content_type).first
+    site_content = SiteContent.find_by(content_type: content_type)
     return site_content if site_content.present?
 
     site_content = SiteContent.new
diff --git a/lib/topic_creator.rb b/lib/topic_creator.rb
index 7356c8b81f0..b361bbc3687 100644
--- a/lib/topic_creator.rb
+++ b/lib/topic_creator.rb
@@ -72,9 +72,9 @@ class TopicCreator
     # When all clients are updated the category variable should
     # be set directly to the contents of the if statement.
     if (@opts[:category].is_a? Integer) || (@opts[:category] =~ /^\d+$/)
-      Category.where(id: @opts[:category]).first
+      Category.find_by(id: @opts[:category])
     else
-      Category.where(name: @opts[:category]).first
+      Category.find_by(name: @opts[:category])
     end
   end
 
diff --git a/lib/topic_retriever.rb b/lib/topic_retriever.rb
index a03966a8ae6..3fb9195f8b2 100644
--- a/lib/topic_retriever.rb
+++ b/lib/topic_retriever.rb
@@ -46,7 +46,7 @@ class TopicRetriever
     end
 
     def fetch_http
-      user = User.where(username_lower: SiteSetting.embed_by_username.downcase).first
+      user = User.find_by(username_lower: SiteSetting.embed_by_username.downcase)
       return if user.blank?
 
       TopicEmbed.import_remote(user, @embed_url)
diff --git a/lib/topic_view.rb b/lib/topic_view.rb
index 86bd1ee99f7..d961a5388a3 100644
--- a/lib/topic_view.rb
+++ b/lib/topic_view.rb
@@ -185,7 +185,7 @@ class TopicView
   def topic_user
     @topic_user ||= begin
       return nil if @user.blank?
-      @topic.topic_users.where(user_id: @user.id).first
+      @topic.topic_users.find_by(user_id: @user.id)
     end
   end
 
diff --git a/spec/components/post_creator_spec.rb b/spec/components/post_creator_spec.rb
index 21fa0435474..d9b939f0572 100644
--- a/spec/components/post_creator_spec.rb
+++ b/spec/components/post_creator_spec.rb
@@ -167,7 +167,7 @@ describe PostCreator do
         first_post = creator.create
 
         # ensure topic user is correct
-        topic_user = first_post.user.topic_users.where(topic_id: first_post.topic_id).first
+        topic_user = first_post.user.topic_users.find_by(topic_id: first_post.topic_id)
         topic_user.should be_present
         topic_user.should be_posted
         topic_user.last_read_post_number.should == first_post.post_number
diff --git a/spec/components/post_destroyer_spec.rb b/spec/components/post_destroyer_spec.rb
index bddab2e01bd..2acd2c6753d 100644
--- a/spec/components/post_destroyer_spec.rb
+++ b/spec/components/post_destroyer_spec.rb
@@ -164,7 +164,7 @@ describe PostDestroyer do
 
     context 'topic_user' do
 
-      let(:topic_user) { second_user.topic_users.where(topic_id: topic.id).first }
+      let(:topic_user) { second_user.topic_users.find_by(topic_id: topic.id) }
 
       it 'clears the posted flag for the second user' do
         topic_user.posted?.should be_false
@@ -275,8 +275,8 @@ describe PostDestroyer do
     it "should delete the post actions" do
       flag = PostAction.act(codinghorror, second_post, PostActionType.types[:off_topic])
       PostDestroyer.new(moderator, second_post).destroy
-      expect(PostAction.where(id: flag.id).first).to be_nil
-      expect(PostAction.where(id: bookmark.id).first).to be_nil
+      expect(PostAction.find_by(id: flag.id)).to be_nil
+      expect(PostAction.find_by(id: bookmark.id)).to be_nil
     end
 
     it 'should update flag counts on the post' do
diff --git a/spec/components/pretty_text_spec.rb b/spec/components/pretty_text_spec.rb
index 03770134060..217c58fc2ba 100644
--- a/spec/components/pretty_text_spec.rb
+++ b/spec/components/pretty_text_spec.rb
@@ -10,7 +10,7 @@ describe PrettyText do
       before(:each) do
         eviltrout = User.new
         eviltrout.stubs(:avatar_template).returns("http://test.localhost/uploads/default/avatars/42d/57c/46ce7ee487/{size}.png")
-        User.expects(:where).with(username_lower: "eviltrout").returns([eviltrout])
+        User.expects(:find_by).with(username_lower: "eviltrout").returns(eviltrout)
       end
 
       it "produces a quote even with new lines in it" do
diff --git a/spec/controllers/categories_controller_spec.rb b/spec/controllers/categories_controller_spec.rb
index ef1cc9d0a92..f6cb6a71987 100644
--- a/spec/controllers/categories_controller_spec.rb
+++ b/spec/controllers/categories_controller_spec.rb
@@ -57,7 +57,7 @@ describe CategoriesController do
                               }
 
           response.status.should == 200
-          category = Category.where(name: "hello").first
+          category = Category.find_by(name: "hello")
           category.category_groups.map{|g| [g.group_id, g.permission_type]}.sort.should == [
             [Group[:everyone].id, readonly],[Group[:staff].id,create_post]
           ]
diff --git a/spec/controllers/session_controller_spec.rb b/spec/controllers/session_controller_spec.rb
index a5d44e0443a..34453be5981 100644
--- a/spec/controllers/session_controller_spec.rb
+++ b/spec/controllers/session_controller_spec.rb
@@ -171,7 +171,7 @@ describe SessionController do
 
     context 'when email is confirmed' do
       before do
-        token = user.email_tokens.where(email: user.email).first
+        token = user.email_tokens.find_by(email: user.email)
         EmailToken.confirm(token.token)
       end
 
diff --git a/spec/controllers/uploads_controller_spec.rb b/spec/controllers/uploads_controller_spec.rb
index a1623d167a4..074bda9a910 100644
--- a/spec/controllers/uploads_controller_spec.rb
+++ b/spec/controllers/uploads_controller_spec.rb
@@ -116,20 +116,20 @@ describe UploadsController do
     it "returns 404 when using external storage" do
       store = stub(internal?: false)
       Discourse.stubs(:store).returns(store)
-      Upload.expects(:where).never
+      Upload.expects(:find_by).never
       get :show, site: "default", id: 1, sha: "1234567890abcdef", extension: "pdf"
       response.response_code.should == 404
     end
 
     it "returns 404 when the upload doens't exist" do
-      Upload.expects(:where).with(id: 2, url: "/uploads/default/2/1234567890abcdef.pdf").returns [nil]
+      Upload.expects(:find_by).with(id: 2, url: "/uploads/default/2/1234567890abcdef.pdf").returns(nil)
       get :show, site: "default", id: 2, sha: "1234567890abcdef", extension: "pdf"
       response.response_code.should == 404
     end
 
     it 'uses send_file' do
       upload = build(:upload)
-      Upload.expects(:where).with(id: 42, url: "/uploads/default/42/66b3ed1503efc936.zip").returns([upload])
+      Upload.expects(:find_by).with(id: 42, url: "/uploads/default/42/66b3ed1503efc936.zip").returns(upload)
 
       controller.stubs(:render)
       controller.expects(:send_file)
diff --git a/spec/controllers/user_badges_controller_spec.rb b/spec/controllers/user_badges_controller_spec.rb
index 87fc240e6ee..70a2fbd0001 100644
--- a/spec/controllers/user_badges_controller_spec.rb
+++ b/spec/controllers/user_badges_controller_spec.rb
@@ -45,7 +45,7 @@ describe UserBadgesController do
       StaffActionLogger.any_instance.expects(:log_badge_grant).once
       xhr :post, :create, badge_id: badge.id, username: user.username
       response.status.should == 200
-      user_badge = UserBadge.where(user: user, badge: badge).first
+      user_badge = UserBadge.find_by(user: user, badge: badge)
       user_badge.should be_present
       user_badge.granted_by.should eq(admin)
     end
@@ -61,7 +61,7 @@ describe UserBadgesController do
       StaffActionLogger.any_instance.expects(:log_badge_grant).never
       xhr :post, :create, badge_id: badge.id, username: user.username, api_key: api_key.key
       response.status.should == 200
-      user_badge = UserBadge.where(user: user, badge: badge).first
+      user_badge = UserBadge.find_by(user: user, badge: badge)
       user_badge.should be_present
       user_badge.granted_by.should eq(Discourse.system_user)
     end
@@ -80,7 +80,7 @@ describe UserBadgesController do
       StaffActionLogger.any_instance.expects(:log_badge_revoke).once
       xhr :delete, :destroy, id: user_badge.id
       response.status.should == 200
-      UserBadge.where(id: user_badge.id).first.should be_nil
+      UserBadge.find_by(id: user_badge.id).should be_nil
     end
   end
 end
diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb
index d2ed036b093..bf2edd38b42 100644
--- a/spec/controllers/users_controller_spec.rb
+++ b/spec/controllers/users_controller_spec.rb
@@ -382,7 +382,7 @@ describe UsersController do
       end
 
       it 'should not result in an active account' do
-        User.where(username: @user.username).first.active.should be_false
+        User.find_by(username: @user.username).active.should be_false
       end
     end
 
diff --git a/spec/jobs/close_topic_spec.rb b/spec/jobs/close_topic_spec.rb
index 8fa249d1dce..d3dfcc8d64e 100644
--- a/spec/jobs/close_topic_spec.rb
+++ b/spec/jobs/close_topic_spec.rb
@@ -8,16 +8,16 @@ describe Jobs::CloseTopic do
   it 'closes a topic that is set to auto-close' do
     topic = Fabricate.build(:topic, auto_close_at: Time.zone.now, user: admin)
     topic.expects(:update_status).with('autoclosed', true, admin)
-    Topic.stubs(:where).returns([topic])
-    User.stubs(:where).returns([admin])
+    Topic.stubs(:find_by).returns(topic)
+    User.stubs(:find_by).returns(admin)
     Jobs::CloseTopic.new.execute( topic_id: 123, user_id: 234 )
   end
 
   shared_examples_for "cases when CloseTopic does nothing" do
     it 'does nothing to the topic' do
       topic.expects(:update_status).never
-      Topic.stubs(:where).returns([topic])
-      User.stubs(:where).returns([admin])
+      Topic.stubs(:find_by).returns(topic)
+      User.stubs(:find_by).returns(admin)
       Jobs::CloseTopic.new.execute( topic_id: 123, user_id: 234 )
     end
   end
diff --git a/spec/models/invite_spec.rb b/spec/models/invite_spec.rb
index c0ca3f8d9aa..0cf6dbb5bf1 100644
--- a/spec/models/invite_spec.rb
+++ b/spec/models/invite_spec.rb
@@ -240,7 +240,7 @@ describe Invite do
       end
 
       context 'invited by another user to the same topic' do
-        let(:coding_horror) { User.where(username: 'CodingHorror').first }
+        let(:coding_horror) { User.find_by(username: "CodingHorror") }
         let!(:another_invite) { topic.invite(coding_horror, 'jake@adventuretime.ooo') }
         let!(:user) { invite.redeem }
 
@@ -250,7 +250,7 @@ describe Invite do
       end
 
       context 'invited by another user to a different topic' do
-        let(:coding_horror) { User.where(username: 'CodingHorror').first }
+        let(:coding_horror) { User.find_by(username: "CodingHorror") }
         let(:another_topic) { Fabricate(:topic, archetype: "private_message", user: coding_horror) }
         let!(:another_invite) { another_topic.invite(coding_horror, 'jake@adventuretime.ooo') }
         let!(:user) { invite.redeem }
diff --git a/spec/models/post_mover_spec.rb b/spec/models/post_mover_spec.rb
index ef2b8353b65..b4e08d09cf8 100644
--- a/spec/models/post_mover_spec.rb
+++ b/spec/models/post_mover_spec.rb
@@ -61,7 +61,7 @@ describe PostMover do
         let!(:new_topic) { topic.move_posts(user, [p2.id, p4.id], title: "new testing topic name", category_id: category.id) }
 
         it "works correctly" do
-          TopicUser.where(user_id: user.id, topic_id: topic.id).first.last_read_post_number.should == p3.post_number
+          TopicUser.find_by(user_id: user.id, topic_id: topic.id).last_read_post_number.should == p3.post_number
 
           new_topic.should be_present
           new_topic.featured_user1_id.should == another_user.id
@@ -93,7 +93,7 @@ describe PostMover do
           topic.highest_post_number.should == p3.post_number
 
           # both the like and was_liked user actions should be correct
-          action = UserAction.where(user_id: another_user.id).first
+          action = UserAction.find_by(user_id: another_user.id)
           action.target_topic_id.should == new_topic.id
         end
       end
@@ -137,7 +137,7 @@ describe PostMover do
           topic.highest_post_number.should == p3.post_number
 
           # Should update last reads
-          TopicUser.where(user_id: user.id, topic_id: topic.id).first.last_read_post_number.should == p3.post_number
+          TopicUser.find_by(user_id: user.id, topic_id: topic.id).last_read_post_number.should == p3.post_number
         end
       end
 
diff --git a/spec/models/post_timing_spec.rb b/spec/models/post_timing_spec.rb
index e1ca8a84e95..47d48efff80 100644
--- a/spec/models/post_timing_spec.rb
+++ b/spec/models/post_timing_spec.rb
@@ -48,15 +48,15 @@ describe PostTiming do
       PostTiming.where(topic_id: topic_id, user_id: 2, post_number: 3).count.should == 1
       PostTiming.where(topic_id: topic_id, user_id: 3, post_number: 3).count.should == 1
 
-      tu = TopicUser.where(topic_id: topic_id, user_id: 1).first
+      tu = TopicUser.find_by(topic_id: topic_id, user_id: 1)
       tu.last_read_post_number.should == 1
       tu.seen_post_count.should == 1
 
-      tu = TopicUser.where(topic_id: topic_id, user_id: 2).first
+      tu = TopicUser.find_by(topic_id: topic_id, user_id: 2)
       tu.last_read_post_number.should == 3
       tu.seen_post_count.should == 3
 
-      tu = TopicUser.where(topic_id: topic_id, user_id: 3).first
+      tu = TopicUser.find_by(topic_id: topic_id, user_id: 3)
       tu.last_read_post_number.should == 3
       tu.seen_post_count.should == 3
 
@@ -113,7 +113,7 @@ describe PostTiming do
       before do
         PostTiming.record_timing(@timing_attrs)
         PostTiming.record_timing(@timing_attrs)
-        @timing = PostTiming.where(topic_id: @post.topic_id, user_id: @coding_horror.id, post_number: @post.post_number).first
+        @timing = PostTiming.find_by(topic_id: @post.topic_id, user_id: @coding_horror.id, post_number: @post.post_number)
       end
 
       it 'creates a timing record' do
diff --git a/spec/models/topic_spec.rb b/spec/models/topic_spec.rb
index 03bd04c3600..38aa5390570 100644
--- a/spec/models/topic_spec.rb
+++ b/spec/models/topic_spec.rb
@@ -282,7 +282,7 @@ describe Topic do
 
 
   context 'private message' do
-    let(:coding_horror) { User.where(username: 'CodingHorror').first }
+    let(:coding_horror) { User.find_by(username: "CodingHorror") }
     let(:evil_trout) { Fabricate(:evil_trout) }
     let(:topic) { Fabricate(:private_message_topic) }
 
@@ -670,7 +670,7 @@ describe Topic do
       it 'updates the last_post_user_id to the second_user' do
         @topic.last_post_user_id.should == @second_user.id
         @topic.last_posted_at.to_i.should == @new_post.created_at.to_i
-        topic_user = @second_user.topic_users.where(topic_id: @topic.id).first
+        topic_user = @second_user.topic_users.find_by(topic_id: @topic.id)
         topic_user.posted?.should be_true
       end
 
diff --git a/spec/models/topic_status_update_spec.rb b/spec/models/topic_status_update_spec.rb
index ff5e2ca9bf2..11ef5e411bd 100644
--- a/spec/models/topic_status_update_spec.rb
+++ b/spec/models/topic_status_update_spec.rb
@@ -23,7 +23,7 @@ describe TopicStatusUpdate do
 
     post.topic.posts.count.should == 2
 
-    tu = TopicUser.where(user_id: user.id).first
+    tu = TopicUser.find_by(user_id: user.id)
     tu.last_read_post_number.should == 2
   end
 end
diff --git a/spec/models/topic_user_spec.rb b/spec/models/topic_user_spec.rb
index ce463c10eef..fab7a1fc9f2 100644
--- a/spec/models/topic_user_spec.rb
+++ b/spec/models/topic_user_spec.rb
@@ -263,7 +263,7 @@ describe TopicUser do
 
     TopicUser.ensure_consistency!
 
-    tu = TopicUser.where(user_id: p1.user_id, topic_id: p1.topic_id).first
+    tu = TopicUser.find_by(user_id: p1.user_id, topic_id: p1.topic_id)
     tu.last_read_post_number.should == p2.post_number
     tu.seen_post_count.should == 2
   end
@@ -278,15 +278,15 @@ describe TopicUser do
       create_post(topic_id: post.topic_id)
 
       # mails posts from earlier topics
-      tu = TopicUser.where(user_id: user3.id, topic_id: post.topic_id).first
+      tu = TopicUser.find_by(user_id: user3.id, topic_id: post.topic_id)
       tu.last_emailed_post_number.should == 2
 
       # mails nothing to random users
-      tu = TopicUser.where(user_id: user1.id, topic_id: post.topic_id).first
+      tu = TopicUser.find_by(user_id: user1.id, topic_id: post.topic_id)
       tu.should be_nil
 
       # mails other user
-      tu = TopicUser.where(user_id: user2.id, topic_id: post.topic_id).first
+      tu = TopicUser.find_by(user_id: user2.id, topic_id: post.topic_id)
       tu.last_emailed_post_number.should == 2
     end
   end
diff --git a/spec/models/upload_spec.rb b/spec/models/upload_spec.rb
index ec2aeec4daa..8b4224116c6 100644
--- a/spec/models/upload_spec.rb
+++ b/spec/models/upload_spec.rb
@@ -49,7 +49,7 @@ describe Upload do
   context "#create_for" do
 
     it "does not create another upload if it already exists" do
-      Upload.expects(:where).with(sha1: image_sha1).returns([upload])
+      Upload.expects(:find_by).with(sha1: image_sha1).returns(upload)
       Upload.expects(:save).never
       Upload.create_for(user_id, image, image_filename, image_filesize).should == upload
     end
@@ -95,18 +95,18 @@ describe Upload do
   context ".get_from_url" do
 
     it "works when the file has been uploaded" do
-      Upload.expects(:where).returns([]).once
+      Upload.expects(:find_by).returns(nil).once
       Upload.get_from_url("/uploads/default/1/10387531.jpg")
     end
 
     it "works when using a cdn" do
       Rails.configuration.action_controller.stubs(:asset_host).returns("http://my.cdn.com")
-      Upload.expects(:where).with(url: "/uploads/default/1/02395732905.jpg").returns([]).once
+      Upload.expects(:find_by).with(url: "/uploads/default/1/02395732905.jpg").returns(nil).once
       Upload.get_from_url("http://my.cdn.com/uploads/default/1/02395732905.jpg")
     end
 
     it "works only when the file has been uploaded" do
-      Upload.expects(:where).never
+      Upload.expects(:find_by).never
       Upload.get_from_url("http://domain.com/my/file.txt")
     end
 
diff --git a/spec/models/user_action_spec.rb b/spec/models/user_action_spec.rb
index d3d13f1c567..07877bf6df6 100644
--- a/spec/models/user_action_spec.rb
+++ b/spec/models/user_action_spec.rb
@@ -116,8 +116,8 @@ describe UserAction do
     context "successful like" do
       before do
         PostAction.act(liker, post, PostActionType.types[:like])
-        @liker_action = liker.user_actions.where(action_type: UserAction::LIKE).first
-        @likee_action = likee.user_actions.where(action_type: UserAction::WAS_LIKED).first
+        @liker_action = liker.user_actions.find_by(action_type: UserAction::LIKE)
+        @likee_action = likee.user_actions.find_by(action_type: UserAction::WAS_LIKED)
       end
 
       it 'should result in correct data assignment' do
@@ -160,7 +160,7 @@ describe UserAction do
 
     describe 'topic action' do
       before do
-        @action = @post.user.user_actions.where(action_type: UserAction::NEW_TOPIC).first
+        @action = @post.user.user_actions.find_by(action_type: UserAction::NEW_TOPIC)
       end
       it 'should exist' do
         @action.should_not be_nil
@@ -169,7 +169,7 @@ describe UserAction do
     end
 
     it 'should not log a post user action' do
-      @post.user.user_actions.where(action_type: UserAction::REPLY).first.should be_nil
+      @post.user.user_actions.find_by(action_type: UserAction::REPLY).should be_nil
     end
 
 
@@ -183,9 +183,9 @@ describe UserAction do
       end
 
       it 'should log user actions correctly' do
-        @response.user.user_actions.where(action_type: UserAction::REPLY).first.should_not be_nil
-        @post.user.user_actions.where(action_type: UserAction::RESPONSE).first.should_not be_nil
-        @mentioned.user_actions.where(action_type: UserAction::MENTION).first.should_not be_nil
+        @response.user.user_actions.find_by(action_type: UserAction::REPLY).should_not be_nil
+        @post.user.user_actions.find_by(action_type: UserAction::RESPONSE).should_not be_nil
+        @mentioned.user_actions.find_by(action_type: UserAction::MENTION).should_not be_nil
         @post.user.user_actions.joins(:target_post).where('posts.post_number = 2').count.should == 1
       end
 
@@ -203,7 +203,7 @@ describe UserAction do
       @post = Fabricate(:post)
       @user = @post.user
       PostAction.act(@user, @post, PostActionType.types[:bookmark])
-      @action = @user.user_actions.where(action_type: UserAction::BOOKMARK).first
+      @action = @user.user_actions.find_by(action_type: UserAction::BOOKMARK)
     end
 
     it 'should create a bookmark action correctly' do
@@ -213,7 +213,7 @@ describe UserAction do
       @action.user_id.should == @user.id
 
       PostAction.remove_act(@user, @post, PostActionType.types[:bookmark])
-      @user.user_actions.where(action_type: UserAction::BOOKMARK).first.should be_nil
+      @user.user_actions.find_by(action_type: UserAction::BOOKMARK).should be_nil
     end
   end
 
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 050d14dff21..4057ede3f3a 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -186,7 +186,7 @@ describe User do
       expect(Post.where(id: @posts.map(&:id))).to be_empty
       @posts.each do |p|
         if p.post_number == 1
-          expect(Topic.where(id: p.topic_id).first).to be_nil
+          expect(Topic.find_by(id: p.topic_id)).to be_nil
         end
       end
     end
@@ -705,7 +705,7 @@ describe User do
 
     context 'when email has been confirmed' do
       it 'should return true' do
-        token = user.email_tokens.where(email: user.email).first
+        token = user.email_tokens.find_by(email: user.email)
         EmailToken.confirm(token.token)
         user.email_confirmed?.should be_true
       end
diff --git a/spec/services/badge_granter_spec.rb b/spec/services/badge_granter_spec.rb
index dcdbd7008c3..a186d6f85a4 100644
--- a/spec/services/badge_granter_spec.rb
+++ b/spec/services/badge_granter_spec.rb
@@ -43,7 +43,7 @@ describe BadgeGranter do
     it 'increments grant_count on the badge and creates a notification' do
       BadgeGranter.grant(badge, user)
       badge.reload.grant_count.should eq(1)
-      user.notifications.where(notification_type: Notification.types[:granted_badge]).first.data_hash["badge_id"].should == badge.id
+      user.notifications.find_by(notification_type: Notification.types[:granted_badge]).data_hash["badge_id"].should == badge.id
     end
 
   end
@@ -58,7 +58,7 @@ describe BadgeGranter do
       badge.reload.grant_count.should eq(1)
       StaffActionLogger.any_instance.expects(:log_badge_revoke).with(user_badge)
       BadgeGranter.revoke(user_badge, revoked_by: admin)
-      UserBadge.where(user: user, badge: badge).first.should_not be_present
+      UserBadge.find_by(user: user, badge: badge).should_not be_present
       badge.reload.grant_count.should eq(0)
       user.notifications.where(notification_type: Notification.types[:granted_badge]).should be_empty
       user.reload.title.should == nil
diff --git a/spec/services/color_scheme_revisor_spec.rb b/spec/services/color_scheme_revisor_spec.rb
index 66d97f8bed9..15ab86d7ac8 100644
--- a/spec/services/color_scheme_revisor_spec.rb
+++ b/spec/services/color_scheme_revisor_spec.rb
@@ -56,7 +56,7 @@ describe ColorSchemeRevisor do
             {name: color.name, hex: 'BEEF99', opacity: 99}
           ]))
         }.to change { color_scheme.reload.version }.by(1)
-        old_version = ColorScheme.where(versioned_id: color_scheme.id, version: color_scheme.version - 1).first
+        old_version = ColorScheme.find_by(versioned_id: color_scheme.id, version: (color_scheme.version - 1))
         old_version.should_not be_nil
         old_version.colors.count.should == color_scheme.colors.count
         old_version.colors_by_name[color.name].hex.should == old_hex
diff --git a/vendor/gems/discourse_task/lib/discourse_task/plugin.rb b/vendor/gems/discourse_task/lib/discourse_task/plugin.rb
index 4f105d2a7d1..79e9bc3dadf 100644
--- a/vendor/gems/discourse_task/lib/discourse_task/plugin.rb
+++ b/vendor/gems/discourse_task/lib/discourse_task/plugin.rb
@@ -59,7 +59,7 @@ module DiscourseTask
     module TopicsControllerMixin
 
       def complete
-        topic = Topic.where(id: params[:topic_id]).first
+        topic = Topic.find_by(id: params[:topic_id])
         guardian.ensure_can_complete_task!(topic)
 
         Topic.transaction do