Navigation Menu

Skip to content
This repository has been archived by the owner on Dec 12, 2021. It is now read-only.

Commit

Permalink
fixing 303 url_formatter
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanb committed Nov 29, 2011
1 parent 92d1a67 commit 042ab69
Show file tree
Hide file tree
Showing 17 changed files with 224 additions and 1 deletion.
1 change: 0 additions & 1 deletion episode-303/url_formatter
Submodule url_formatter deleted from 3716c8
4 changes: 4 additions & 0 deletions episode-303/url_formatter/.gitignore
@@ -0,0 +1,4 @@
*.gem
.bundle
Gemfile.lock
pkg/*
1 change: 1 addition & 0 deletions episode-303/url_formatter/.rspec
@@ -0,0 +1 @@
--color
2 changes: 2 additions & 0 deletions episode-303/url_formatter/.travis.yml
@@ -0,0 +1,2 @@
rvm:
- 1.9.2
3 changes: 3 additions & 0 deletions episode-303/url_formatter/CHANGELOG.md
@@ -0,0 +1,3 @@
## v0.0.1

* initial release
4 changes: 4 additions & 0 deletions episode-303/url_formatter/Gemfile
@@ -0,0 +1,4 @@
source "http://rubygems.org"

# Specify your gem's dependencies in url_formatter.gemspec
gemspec
20 changes: 20 additions & 0 deletions episode-303/url_formatter/LICENSE
@@ -0,0 +1,20 @@
Copyright (c) 2011 Ryan Bates

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 changes: 34 additions & 0 deletions episode-303/url_formatter/README.md
@@ -0,0 +1,34 @@
# URL Formatter [![Build Status](https://secure.travis-ci.org/ryanb/url_formatter.png)](http://travis-ci.org/ryanb/url_formatter)

Format and validate a URL attribute in Active Record. This is an example gem created for [RailsCasts episode #301](http://railscasts.com/episodes/301-extracting-a-ruby-gem).


## Installation

Add to your Gemfile and run the `bundle` command to install it.

```ruby
gem "url_formatter"
```

**Requires Ruby 1.9.2 or later.**


## Usage

Call [format_url](http://rubydoc.info/github/ryanb/url_formatter/master/UrlFormatter/ModelAdditions:format_url) in an ActiveRecord class and pass the name of the attribute you wish to format into a URL and validate.

```ruby
class Comment < ActiveRecord::Base
format_url :website
end
```

This will automatically add "http://" to the beginning of the `website` attribute upon saving if no protocol is present. It will also do validation to ensure it looks like a URL.


## Development

Questions or problems? Please post them on the [issue tracker](https://github.com/ryanb/url_formatter/issues). You can contribute changes by forking the project and submitting a pull request. You can ensure the tests passing by running `bundle` and `rake`.

This gem is created by Ryan Bates and is under the MIT License.
6 changes: 6 additions & 0 deletions episode-303/url_formatter/Rakefile
@@ -0,0 +1,6 @@
require "bundler/gem_tasks"
require 'rspec/core/rake_task'

RSpec::Core::RakeTask.new(:spec)

task default: :spec
17 changes: 17 additions & 0 deletions episode-303/url_formatter/lib/url_formatter.rb
@@ -0,0 +1,17 @@
require "url_formatter/version"
require "url_formatter/model_additions"
require "url_formatter/railtie" if defined? Rails

module UrlFormatter
def self.format_url(url)
if url.to_s !~ url_regexp && "http://#{url}" =~ url_regexp
"http://#{url}"
else
url
end
end

def self.url_regexp
/^https?:\/\/([^\s:@]+:[^\s:@]*@)?[-[[:alnum:]]]+(\.[-[[:alnum:]]]+)+\.?(:\d{1,5})?([\/?]\S*)?$/iux
end
end
20 changes: 20 additions & 0 deletions episode-303/url_formatter/lib/url_formatter/model_additions.rb
@@ -0,0 +1,20 @@
module UrlFormatter
module ModelAdditions
# To format and validate a URL attribute, call <tt>format_url</tt>
# in any Active Record model class and pass it the name of an attribute.
#
# class User < ActiveRecord::Base
# format_url :website
# end
#
# This will add a <tt>before_validation</tt> callback to add "http://" to
# the attribute if a protocol doesn't exist already. It then validates the
# format of the URL.
def format_url(attribute)
before_validation do
send("#{attribute}=", UrlFormatter.format_url(send(attribute)))
end
validates_format_of attribute, with: UrlFormatter.url_regexp, message: "is not a valid URL"
end
end
end
9 changes: 9 additions & 0 deletions episode-303/url_formatter/lib/url_formatter/railtie.rb
@@ -0,0 +1,9 @@
module UrlFormatter
class Railtie < Rails::Railtie
initializer 'url_formatter.model_additions' do
ActiveSupport.on_load :active_record do
extend ModelAdditions
end
end
end
end
3 changes: 3 additions & 0 deletions episode-303/url_formatter/lib/url_formatter/version.rb
@@ -0,0 +1,3 @@
module UrlFormatter
VERSION = "0.0.2.alpha"
end
2 changes: 2 additions & 0 deletions episode-303/url_formatter/spec/spec_helper.rb
@@ -0,0 +1,2 @@
require 'url_formatter'
require 'supermodel'
@@ -0,0 +1,22 @@
require 'spec_helper'

class Comment < SuperModel::Base
include ActiveModel::Validations::Callbacks
extend UrlFormatter::ModelAdditions
format_url :website
end

describe UrlFormatter::ModelAdditions do
it "adds http:// to URL upon saving" do
Comment.create!(website: "example.com").website.should eq("http://example.com")
Comment.create!(website: "http://example.com").website.should eq("http://example.com")
end

it "validates URL format" do
comment = Comment.new(website: "foo bar")
comment.should_not be_valid
comment.errors[:website].should eq(["is not a valid URL"])
comment.website = "example.com"
comment.should be_valid
end
end
53 changes: 53 additions & 0 deletions episode-303/url_formatter/spec/url_formatter_spec.rb
@@ -0,0 +1,53 @@
# encoding: utf-8
require 'spec_helper'

describe UrlFormatter do
describe ".format_url" do
it "adds http:// to a URL if not provided" do
UrlFormatter.format_url("example.com").should eq("http://example.com")
end

it "does not add http:// to a URL if already provided" do
UrlFormatter.format_url("http://example.com").should eq("http://example.com")
end

it "returns an invalid URL unchanged" do
UrlFormatter.format_url("foo bar").should eq("foo bar")
UrlFormatter.format_url(nil).should eq(nil)
end
end

describe ".url_regexp" do
it "matches valid URLs" do
[
'http://example.com/',
'HTTP://E-XAMLE.COM',
'https://example.co.uk./foo',
'http://example.com:8080',
'http://www.example.com/anything/after?slash',
'http://www.example.com?anything_after=question',
'http://user123:sEcr3t@example.com',
'http://user123:@example.com',
'http://example.com/~user',
'http://1.2.3.4:8080',
'http://ütf8.com',
].each do |url|
url.should match(UrlFormatter.url_regexp)
end
end

it "does not match invalid URLs" do
[
"www.example.com",
"http://",
"http://example..com",
"http://e xample.com",
"http://example.com/foo bar",
"http://example", # technically valid but not what we want from user
"other://example.com", # we also don't want other protocols
].each do |url|
url.should_not match(UrlFormatter.url_regexp)
end
end
end
end
24 changes: 24 additions & 0 deletions episode-303/url_formatter/url_formatter.gemspec
@@ -0,0 +1,24 @@
# -*- encoding: utf-8 -*-
$:.push File.expand_path("../lib", __FILE__)
require "url_formatter/version"

Gem::Specification.new do |s|
s.name = "url_formatter"
s.version = UrlFormatter::VERSION
s.authors = ["Ryan Bates"]
s.email = ["ryan@railscasts.com"]
s.homepage = "https://github.com/ryanb/url_formatter"
s.summary = %q{Format and validate a URL in Active Record}
s.description = %q{Example of creating a Ruby Gem for RailsCasts episode #301}

s.rubyforge_project = "url_formatter"

s.files = `git ls-files`.split("\n")
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
s.require_paths = ["lib"]

s.add_development_dependency "rake"
s.add_development_dependency "rspec"
s.add_development_dependency "supermodel"
end

0 comments on commit 042ab69

Please sign in to comment.