diff --git a/app/models/ci/variable.rb b/app/models/ci/variable.rb
index 94d9e2b3208d040510262f7965bded9849b764d7..2c8698d8b5de8d4f2605641a1dc10185cb751402 100644
--- a/app/models/ci/variable.rb
+++ b/app/models/ci/variable.rb
@@ -4,10 +4,10 @@ module Ci
 
     belongs_to :project, foreign_key: :gl_project_id
 
-    validates_uniqueness_of :key, scope: :gl_project_id
     validates :key,
       presence: true,
-      length: { within: 0..255 },
+      uniqueness: { scope: :gl_project_id },
+      length: { maximum: 255 },
       format: { with: /\A[a-zA-Z0-9_]+\z/,
                 message: "can contain only letters, digits and '_'." }
 
diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb
index 69d8afc45da99ebe6ed7ed47a442c95569ed0dbb..0ea7b1b1098e3786c5d850613b2013a9dd4e3ab2 100644
--- a/app/models/concerns/issuable.rb
+++ b/app/models/concerns/issuable.rb
@@ -41,7 +41,7 @@ module Issuable
     has_one :metrics
 
     validates :author, presence: true
-    validates :title, presence: true, length: { within: 0..255 }
+    validates :title, presence: true, length: { maximum: 255 }
 
     scope :authored, ->(user) { where(author_id: user) }
     scope :assigned_to, ->(u) { where(assignee_id: u.id)}
diff --git a/app/models/environment.rb b/app/models/environment.rb
index a7f4156fc2ef53a71eef7ec82ee2e9b415cc1d48..96700143ddd9893eb4d930eb4f5e4a8e59670e65 100644
--- a/app/models/environment.rb
+++ b/app/models/environment.rb
@@ -9,7 +9,7 @@ class Environment < ActiveRecord::Base
   validates :name,
             presence: true,
             uniqueness: { scope: :project_id },
-            length: { within: 0..255 },
+            length: { maximum: 255 },
             format: { with: Gitlab::Regex.environment_name_regex,
                       message: Gitlab::Regex.environment_name_regex_message }
 
diff --git a/app/models/key.rb b/app/models/key.rb
index ff8dda2dc892ba9e6365def0b681e9c70a3c7d54..a5d25409730cb0f699eb3847d8c4626c6b9efa80 100644
--- a/app/models/key.rb
+++ b/app/models/key.rb
@@ -8,10 +8,18 @@ class Key < ActiveRecord::Base
 
   before_validation :generate_fingerprint
 
-  validates :title, presence: true, length: { within: 0..255 }
-  validates :key, presence: true, length: { within: 0..5000 }, format: { with: /\A(ssh|ecdsa)-.*\Z/ }
-  validates :key, format: { without: /\n|\r/, message: 'should be a single line' }
-  validates :fingerprint, uniqueness: true, presence: { message: 'cannot be generated' }
+  validates :title,
+    presence: true,
+    length: { maximum: 255 }
+  validates :key,
+    presence: true,
+    length: { maximum: 5000 },
+    format: { with: /\A(ssh|ecdsa)-.*\Z/ }
+  validates :key,
+    format: { without: /\n|\r/, message: 'should be a single line' }
+  validates :fingerprint,
+    uniqueness: true,
+    presence: { message: 'cannot be generated' }
 
   delegate :name, :email, to: :user, prefix: true
 
diff --git a/app/models/namespace.rb b/app/models/namespace.rb
index 891dffac648e639eb2d49a95114e7035bf4e3d82..7a545f752b6bbb20bba78bdf4ee870e9221d0bce 100644
--- a/app/models/namespace.rb
+++ b/app/models/namespace.rb
@@ -12,17 +12,17 @@ class Namespace < ActiveRecord::Base
 
   validates :owner, presence: true, unless: ->(n) { n.type == "Group" }
   validates :name,
-    length: { within: 0..255 },
-    namespace_name: true,
     presence: true,
-    uniqueness: true
+    uniqueness: true,
+    length: { maximum: 255 },
+    namespace_name: true
 
-  validates :description, length: { within: 0..255 }
+  validates :description, length: { maximum: 255 }
   validates :path,
-    length: { within: 1..255 },
-    namespace: true,
     presence: true,
-    uniqueness: { case_sensitive: false }
+    uniqueness: { case_sensitive: false },
+    length: { maximum: 255 },
+    namespace: true
 
   delegate :name, to: :owner, allow_nil: true, prefix: true
 
diff --git a/app/models/project.rb b/app/models/project.rb
index f01cb613b8575c75b39fc1a7f42a15492cec47c7..e783e455a4906b4c17fc72a19ed3b5951f08a3e0 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -172,13 +172,13 @@ class Project < ActiveRecord::Base
   validates :description, length: { maximum: 2000 }, allow_blank: true
   validates :name,
     presence: true,
-    length: { within: 0..255 },
+    length: { maximum: 255 },
     format: { with: Gitlab::Regex.project_name_regex,
               message: Gitlab::Regex.project_name_regex_message }
   validates :path,
     presence: true,
     project_path: true,
-    length: { within: 0..255 },
+    length: { maximum: 255 },
     format: { with: Gitlab::Regex.project_path_regex,
               message: Gitlab::Regex.project_path_regex_message }
   validates :namespace, presence: true
diff --git a/app/models/snippet.rb b/app/models/snippet.rb
index 8ff4e7ae718ea940f8030b2c76ec040f62067a87..99493e561ab99142eb22d29ae1f680085a84348c 100644
--- a/app/models/snippet.rb
+++ b/app/models/snippet.rb
@@ -27,9 +27,9 @@ class Snippet < ActiveRecord::Base
   delegate :name, :email, to: :author, prefix: true, allow_nil: true
 
   validates :author, presence: true
-  validates :title, presence: true, length: { within: 0..255 }
+  validates :title, presence: true, length: { maximum: 255 }
   validates :file_name,
-    length: { within: 0..255 },
+    length: { maximum: 255 },
     format: { with: Gitlab::Regex.file_name_regex,
               message: Gitlab::Regex.file_name_regex_message }
 
@@ -94,6 +94,10 @@ class Snippet < ActiveRecord::Base
     0
   end
 
+  def file_name
+    super.to_s
+  end
+
   # alias for compatibility with blobs and highlighting
   def path
     file_name
diff --git a/spec/lib/gitlab/github_import/importer_spec.rb b/spec/lib/gitlab/github_import/importer_spec.rb
index 000b9aa6f83a30d76748a6ad01cb0fd7e8871da8..9e027839f592931b286c1af5b687b4eed548e40a 100644
--- a/spec/lib/gitlab/github_import/importer_spec.rb
+++ b/spec/lib/gitlab/github_import/importer_spec.rb
@@ -155,7 +155,7 @@ describe Gitlab::GithubImport::Importer, lib: true do
           message: 'The remote data could not be fully imported.',
           errors: [
             { type: :label, url: "https://api.github.com/repos/octocat/Hello-World/labels/bug", errors: "Validation failed: Title can't be blank, Title is invalid" },
-            { type: :issue, url: "https://api.github.com/repos/octocat/Hello-World/issues/1348", errors: "Validation failed: Title can't be blank, Title is too short (minimum is 0 characters)" },
+            { type: :issue, url: "https://api.github.com/repos/octocat/Hello-World/issues/1348", errors: "Validation failed: Title can't be blank" },
             { type: :wiki, errors: "Gitlab::Shell::Error" },
             { type: :release, url: 'https://api.github.com/repos/octocat/Hello-World/releases/2', errors: "Validation failed: Description can't be blank" }
           ]
diff --git a/spec/models/ci/variable_spec.rb b/spec/models/ci/variable_spec.rb
index 4e7833c31623f31ed37a5f8503735047c5f3394e..bee9f7148497e91c2e59ff3f3b84f99cb208fc20 100644
--- a/spec/models/ci/variable_spec.rb
+++ b/spec/models/ci/variable_spec.rb
@@ -5,6 +5,13 @@ describe Ci::Variable, models: true do
 
   let(:secret_value) { 'secret' }
 
+  it { is_expected.to validate_presence_of(:key) }
+  it { is_expected.to validate_uniqueness_of(:key).scoped_to(:gl_project_id) }
+  it { is_expected.to validate_length_of(:key).is_at_most(255) }
+  it { is_expected.to allow_value('foo').for(:key) }
+  it { is_expected.not_to allow_value('foo bar').for(:key) }
+  it { is_expected.not_to allow_value('foo/bar').for(:key) }
+
   before :each do
     subject.value = secret_value
   end
diff --git a/spec/models/concerns/issuable_spec.rb b/spec/models/concerns/issuable_spec.rb
index 6f84bffe046fac2e85d1bd4d9759602c88e59b0c..4fa06a8c60ac97d6d817662eb1880e8d1cfc4a42 100644
--- a/spec/models/concerns/issuable_spec.rb
+++ b/spec/models/concerns/issuable_spec.rb
@@ -35,7 +35,7 @@ describe Issue, "Issuable" do
     it { is_expected.to validate_presence_of(:iid) }
     it { is_expected.to validate_presence_of(:author) }
     it { is_expected.to validate_presence_of(:title) }
-    it { is_expected.to validate_length_of(:title).is_at_least(0).is_at_most(255) }
+    it { is_expected.to validate_length_of(:title).is_at_most(255) }
   end
 
   describe "Scope" do
diff --git a/spec/models/environment_spec.rb b/spec/models/environment_spec.rb
index d06665197db701869276fb5adf20f7e7157ddd78..c8170164898640e2a49bc42729580745f1168bc8 100644
--- a/spec/models/environment_spec.rb
+++ b/spec/models/environment_spec.rb
@@ -13,9 +13,9 @@ describe Environment, models: true do
 
   it { is_expected.to validate_presence_of(:name) }
   it { is_expected.to validate_uniqueness_of(:name).scoped_to(:project_id) }
-  it { is_expected.to validate_length_of(:name).is_within(0..255) }
+  it { is_expected.to validate_length_of(:name).is_at_most(255) }
 
-  it { is_expected.to validate_length_of(:external_url).is_within(0..255) }
+  it { is_expected.to validate_length_of(:external_url).is_at_most(255) }
 
   # To circumvent a not null violation of the name column:
   # https://github.com/thoughtbot/shoulda-matchers/issues/336
diff --git a/spec/models/key_spec.rb b/spec/models/key_spec.rb
index 90731f554705e71bc4194c20e23be3dba0d9c7a0..2a33d819138c1d71b091dc79c50294305ab53de4 100644
--- a/spec/models/key_spec.rb
+++ b/spec/models/key_spec.rb
@@ -7,9 +7,13 @@ describe Key, models: true do
 
   describe "Validation" do
     it { is_expected.to validate_presence_of(:title) }
+    it { is_expected.to validate_length_of(:title).is_at_most(255) }
+
     it { is_expected.to validate_presence_of(:key) }
-    it { is_expected.to validate_length_of(:title).is_within(0..255) }
-    it { is_expected.to validate_length_of(:key).is_within(0..5000) }
+    it { is_expected.to validate_length_of(:key).is_at_most(5000) }
+    it { is_expected.to allow_value('ssh-foo').for(:key) }
+    it { is_expected.to allow_value('ecdsa-foo').for(:key) }
+    it { is_expected.not_to allow_value('foo-bar').for(:key) }
   end
 
   describe "Methods" do
diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb
index 431b3e4435ff200042d61dc3afd95d5794bc4e65..ba0ed4a36035de088c293660c7adac7cccdb78bd 100644
--- a/spec/models/namespace_spec.rb
+++ b/spec/models/namespace_spec.rb
@@ -4,11 +4,18 @@ describe Namespace, models: true do
   let!(:namespace) { create(:namespace) }
 
   it { is_expected.to have_many :projects }
-  it { is_expected.to validate_presence_of :name }
+
+  it { is_expected.to validate_presence_of(:name) }
   it { is_expected.to validate_uniqueness_of(:name) }
-  it { is_expected.to validate_presence_of :path }
+  it { is_expected.to validate_length_of(:name).is_at_most(255) }
+
+  it { is_expected.to validate_length_of(:description).is_at_most(255) }
+
+  it { is_expected.to validate_presence_of(:path) }
   it { is_expected.to validate_uniqueness_of(:path) }
-  it { is_expected.to validate_presence_of :owner }
+  it { is_expected.to validate_length_of(:path).is_at_most(255) }
+
+  it { is_expected.to validate_presence_of(:owner) }
 
   describe "Mass assignment" do
   end
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 8abcce42ce05d6e2ce6538c25ca4b0f2905a94f1..f7c8c97fdee5565be556648cb0028e50b64b47be 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -131,14 +131,18 @@ describe Project, models: true do
 
     it { is_expected.to validate_presence_of(:name) }
     it { is_expected.to validate_uniqueness_of(:name).scoped_to(:namespace_id) }
-    it { is_expected.to validate_length_of(:name).is_within(0..255) }
+    it { is_expected.to validate_length_of(:name).is_at_most(255) }
 
     it { is_expected.to validate_presence_of(:path) }
     it { is_expected.to validate_uniqueness_of(:path).scoped_to(:namespace_id) }
-    it { is_expected.to validate_length_of(:path).is_within(0..255) }
-    it { is_expected.to validate_length_of(:description).is_within(0..2000) }
+    it { is_expected.to validate_length_of(:path).is_at_most(255) }
+
+    it { is_expected.to validate_length_of(:description).is_at_most(2000) }
+
     it { is_expected.to validate_presence_of(:creator) }
+
     it { is_expected.to validate_presence_of(:namespace) }
+
     it { is_expected.to validate_presence_of(:repository_storage) }
 
     it 'does not allow new projects beyond user limits' do
diff --git a/spec/models/snippet_spec.rb b/spec/models/snippet_spec.rb
index f62f6bacbaa8fc82dacb663f32072b8dc06decbc..279dc30c3571f10dbef5e80ccca9553956a8c673 100644
--- a/spec/models/snippet_spec.rb
+++ b/spec/models/snippet_spec.rb
@@ -23,9 +23,9 @@ describe Snippet, models: true do
     it { is_expected.to validate_presence_of(:author) }
 
     it { is_expected.to validate_presence_of(:title) }
-    it { is_expected.to validate_length_of(:title).is_within(0..255) }
+    it { is_expected.to validate_length_of(:title).is_at_most(255) }
 
-    it { is_expected.to validate_length_of(:file_name).is_within(0..255) }
+    it { is_expected.to validate_length_of(:file_name).is_at_most(255) }
 
     it { is_expected.to validate_presence_of(:content) }
 
@@ -46,6 +46,26 @@ describe Snippet, models: true do
     end
   end
 
+  describe '#file_name' do
+    let(:project) { create(:empty_project) }
+
+    context 'file_name is nil' do
+      let(:snippet) { create(:snippet, project: project, file_name: nil) }
+
+      it 'returns an empty string' do
+        expect(snippet.file_name).to eq ''
+      end
+    end
+
+    context 'file_name is not nil' do
+      let(:snippet) { create(:snippet, project: project, file_name: 'foo.txt') }
+
+      it 'returns the file_name' do
+        expect(snippet.file_name).to eq 'foo.txt'
+      end
+    end
+  end
+
   describe "#content_html_invalidated?" do
     let(:snippet) { create(:snippet, content: "md", content_html: "html", file_name: "foo.md") }
     it "invalidates the HTML cache of content when the filename changes" do
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 14c891994d0d221c56e4bf2daeffc3949b5adcfa..95fe2dc65d95d7b557b1be9f4853420cd3529ac8 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -79,7 +79,7 @@ describe User, models: true do
     it { is_expected.to allow_value(0).for(:projects_limit) }
     it { is_expected.not_to allow_value(-1).for(:projects_limit) }
 
-    it { is_expected.to validate_length_of(:bio).is_within(0..255) }
+    it { is_expected.to validate_length_of(:bio).is_at_most(255) }
 
     it_behaves_like 'an object with email-formated attributes', :email do
       subject { build(:user) }
diff --git a/spec/requests/api/deploy_keys_spec.rb b/spec/requests/api/deploy_keys_spec.rb
index 5fa7299044e1faf68513e80057c5daa9252a960b..aabab8e6ae6efd83cc0c0a7589d1aed1bf420287 100644
--- a/spec/requests/api/deploy_keys_spec.rb
+++ b/spec/requests/api/deploy_keys_spec.rb
@@ -75,7 +75,6 @@ describe API::DeployKeys, api: true  do
       expect(response).to have_http_status(400)
       expect(json_response['message']['key']).to eq([
         'can\'t be blank',
-        'is too short (minimum is 0 characters)',
         'is invalid'
       ])
     end
@@ -85,8 +84,7 @@ describe API::DeployKeys, api: true  do
 
       expect(response).to have_http_status(400)
       expect(json_response['message']['title']).to eq([
-        'can\'t be blank',
-        'is too short (minimum is 0 characters)'
+        'can\'t be blank'
       ])
     end
 
diff --git a/spec/support/matchers/is_within.rb b/spec/support/matchers/is_within.rb
deleted file mode 100644
index 0c35fc7e899b71e01613aaa2dd04427280773107..0000000000000000000000000000000000000000
--- a/spec/support/matchers/is_within.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# Extend shoulda-matchers
-module Shoulda::Matchers::ActiveModel
-  class ValidateLengthOfMatcher
-    # Shortcut for is_at_least and is_at_most
-    def is_within(range)
-      is_at_least(range.min) && is_at_most(range.max)
-    end
-  end
-end