Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions lib/validate_url.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def validate_each(record, attribute, value)
if value.respond_to?(:each)
# Error out if we're not allowing arrays
if !options.include?(:accept_array) || !options.fetch(:accept_array)
record.errors.add(attribute, :url, **filtered_options(value))
record.errors.add(attribute, message, **filtered_options(value))
end

# We have to manually handle `:allow_nil` and `:allow_blank` since it's not caught by
Expand All @@ -50,20 +50,25 @@ def filtered_options(value)
end

def validate_url(record, attribute, value, schemes)
uri = URI.parse(URI::Parser.new.escape(value))
uri = value && URI.parse(URI::Parser.new.escape(value))
host = uri && uri.host
scheme = uri && uri.scheme

valid_host = host && !host.empty?
valid_raw_url = scheme && value =~ /\A#{URI::regexp([scheme])}\z/
valid_scheme = host && scheme && schemes.include?(scheme)
valid_no_local = !options.fetch(:no_local) || (host && host.include?('.'))
valid_suffix = !options.fetch(:public_suffix) || (host && PublicSuffix.valid?(host, :default_rule => nil))

unless valid_raw_url && valid_scheme && valid_no_local && valid_suffix
record.errors.add(attribute, options.fetch(:message), value: value)
unless valid_host && valid_raw_url && valid_scheme && valid_no_local && valid_suffix
record.errors.add(attribute, message, value: value)
end
rescue URI::InvalidURIError, URI::InvalidComponentError
record.errors.add(attribute, :url, **filtered_options(value))
record.errors.add(attribute, message, **filtered_options(value))
end

def message
options.fetch(:message)
end
end

Expand Down
9 changes: 9 additions & 0 deletions spec/resources/user_with_accept_array_with_message.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
require 'active_model/validations'

class UserWithAcceptArrayWithMessage
include ActiveModel::Validations

attr_accessor :homepage

validates :homepage, url: { accept_array: true, message: 'wrong' }
end
1 change: 1 addition & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
autoload :UserWithNoLocal, 'resources/user_with_no_local'
autoload :UserWithPublicSuffix, 'resources/user_with_public_suffix'
autoload :UserWithAcceptArray, 'resources/user_with_accept_array'
autoload :UserWithAcceptArrayWithMessage, 'resources/user_with_accept_array_with_message'
autoload :UserWithAcceptArrayWithNil, 'resources/user_with_accept_array_with_nil'
autoload :UserWithAcceptArrayWithBlank, 'resources/user_with_accept_array_with_blank'

Expand Down
18 changes: 18 additions & 0 deletions spec/validate_url_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,17 @@
end
end

context "with accept array with message" do
let!(:user) { UserWithAcceptArrayWithMessage.new }

it "uses the custom message" do
user.homepage = ["https://foo.com", "https://foo bar.com"]
user.valid?

expect(user.errors[:homepage]).to eq(["wrong"])
end
end

context 'with legacy syntax' do
let!(:user) { UserWithLegacySyntax.new }

Expand Down Expand Up @@ -350,5 +361,12 @@

expect(user.errors[:homepage]).to eq(['wrong'])
end

it 'uses custom message for URIs that can not be parsed' do
user.homepage = ':::'
user.valid?

expect(user.errors[:homepage]).to eq(['wrong'])
end
end
end