Skip to content

Instantly share code, notes, and snippets.

@bak
Created October 30, 2009 03:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bak/222079 to your computer and use it in GitHub Desktop.
Save bak/222079 to your computer and use it in GitHub Desktop.
# Set up git repository
git :init
# Copy database.yml for distribution use
run "cp config/database.yml config/database.yml.example"
# Set up .gitignore files
run %{find . -type d -empty | xargs -I xxx touch xxx/.gitignore}
file '.gitignore', <<-END
.DS_Store
coverage/*
log/*.log
db/*.db
db/*.sqlite3
db/schema.rb
tmp/**/*
doc/api
doc/app
config/database.yml
coverage/*
END
# Install plugins
plugin 'exception_notifier', :git => 'git://github.com/rails/exception_notification.git'
plugin 'asset_packager', :git => 'git://github.com/sbecker/asset_packager.git'
plugin 'authlogic', :git => 'git://github.com/binarylogic/authlogic.git'
plugin 'rails-authorization-plugin', :git => 'git://github.com/DocSavage/rails-authorization-plugin.git'
plugin 'will_paginate', :git => 'git://github.com/mislav/will_paginate.git'
plugin 'shoulda', :git => 'git://github.com/thoughtbot/shoulda.git'
plugin 'factory_girl', :git => 'git://github.com/thoughtbot/factory_girl.git'
plugin 'paperclip', :git => 'git://github.com/thoughtbot/paperclip.git'
# Install all gems
gem 'ruby-debug'
gem 'rubypants'
rake('gems:install', :sudo => true)
rake('gems:unpack')
# Set up sessions, RSpec, user model, etc, and run migrations
rake('db:sessions:create')
generate("session", "user_session")
generate("controller", "user_sessions")
generate("model", "user")
run "rm db/migrate/*_create_users.rb"
file 'db/migrate/20090723072300_create_users.rb',
%q{class CreateUsers < ActiveRecord::Migration
def self.up
create_table :users do |t|
t.string :email
t.string :display_name
t.string :crypted_password
t.string :password_salt
t.string :persistence_token
t.string :single_access_token, :null => false # optional, see Authlogic::Session::Params
t.string :perishable_token, :null => false # optional, see Authlogic::Session::Perishability
t.integer :login_count, :null => false, :default => 0 # optional, see Authlogic::Session::MagicColumns
t.integer :failed_login_count, :null => false, :default => 0 # optional, see Authlogic::Session::MagicColumns
t.datetime :last_request_at # optional, see Authlogic::Session::MagicColumns
t.datetime :current_login_at # optional, see Authlogic::Session::MagicColumns
t.datetime :last_login_at # optional, see Authlogic::Session::MagicColumns
t.string :current_login_ip # optional, see Authlogic::Session::MagicColumns
t.string :last_login_ip # optional, see Authlogic::Session::MagicColumns
t.timestamps
end
add_index :users, :perishable_token
add_index :users, :email
end
def self.down
drop_table :users
end
end
}
generate("controller", "users")
generate("role_model", "Role")
rake('db:migrate')
rakefile "bootstrap.rake", <<HERE
namespace :app do
task :bootstrap => :environment do
admin_user = User.create(:email => "admin@example.com", :password => "letmein", :password_confirmation => "letmein")
admin_role = Role.create(:name => "admin")
admin_user.roles << admin_role
end
task :seed do
end
end
HERE
#======================
# APP
#----------------------
# --- Password Resets ---
file 'app/controllers/password_resets_controller',
%q{class PasswordResetsController < ApplicationController
before_filter :load_user_using_perishable_token, :only => [:edit, :update]
before_filter :require_no_user
def new
render
end
def create
@user = User.find_by_email(params[:email])
if @user
@user.deliver_password_reset_instructions!
flash[:notice] = "Instructions to reset your password have been emailed to you. " +
"Please check your email."
redirect_to root_url
else
flash[:notice] = "No user was found with that email address"
render :action => :new
end
end
def edit
render
end
def update
@user.password = params[:user][:password]
@user.password_confirmation = params[:user][: password_confirmation]
if @user.save
flash[:notice] = "Password successfully updated"
redirect_to account_url
else
render :action => :edit
end
end
private
def load_user_using_perishable_token
@user = User.find_using_perishable_token(params[:id])
unless @user
flash[:notice] = "We're sorry, but we could not locate your account. " +
"If you are having issues try copying and pasting the URL " +
"from your email into your browser or restarting the " +
"reset password process."
redirect_to root_url
end
end
end
}
file 'app/views/password_resets/edit.html.erb',
%q{<% form_for @user, :url => password_reset_path, :method => :put do |f| %>
<%= f.error_messages %>
<fieldset>
<legend>Change My Password</legend>
<p>
<%= f.label :password %><br />
<%= f.password_field :password %>
</p>
<p>
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %>
</p>
</fieldset>
<%= f.submit "Update my password and log me in" %>
<% end %>
}
file 'app/views/password_resets/new.html.erb',
%q{<h1>Forgot Password</h1>
<p>Fill out the form below and instructions to reset your password will be emailed to you:</p>
<% form_tag password_resets_path do %>
<fieldset>
<p>
<label>Email:</label><br />
<%= text_field_tag "email" %>
</p>
</fieldset>
<%= submit_tag "Reset my password" %>
<% end %>
}
# --- Routing ---
file 'config/routes.rb',
%q{ActionController::Routing::Routes.draw do |map|
map.resources :password_resets
map.resource :account, :controller => "users"
map.resources :users
map.resource :user_session
map.login 'login', :controller => 'user_sessions', :action => 'new'
map.logout 'logout', :controller => 'user_sessions', :action => 'destroy'
map.root :controller => 'application'
end
}
# --- Application Base ---
file 'app/helpers/application_helper.rb',
%q{module ApplicationHelper
def body_class
"#{controller.controller_name} #{controller.controller_name}-#{controller.action_name}"
end
# creates the navigation tabs, highlighting if we are in that part of the site
# "that part of the site," meaning a parent in a nested resource relationship
def nav_to(label, location)
if request.path == location # "/" or "/admin"
link_to(label, location, :class => "current")
elsif "/#{request.path.split('/')[1..2].join('/')}" == (location) # "/admin/entries"
link_to(label, location, :class => "current")
else
link_to(label, location)
end
end
end
}
file 'app/views/layouts/_flashes.html.erb',
%q{<div id="flash">
<% flash.each do |key, value| -%>
<div id="flash_<%= key %>"><%=h value %></div>
<% end -%>
</div>
}
file 'app/views/shared/_navigation.html.erb',
%q{<div id="navigation">
<ul>
<% navigation_items.each do |navigation_item| -%>
<li><%= nav_to navigation_item[0], navigation_item[1] %></li>
<% end -%>
</ul>
</div>
}
file 'app/views/application/index.html.erb',
%q{
<h1>IT WORKS</h1>
}
file 'app/views/layouts/application.html.erb',
%q{<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>New Project</title>
<%= stylesheet_link_tag 'screen', :media => 'all', :cache => true %>
<%= javascript_include_tag :defaults, :cache => true %>
</head>
<body class="<%= body_class %>">
<%= render :partial => 'layouts/flashes' -%>
<%= render :partial => 'shared/navigation', :locals => {:navigation_items => @navigation_items} -%>
<%= yield %>
</body>
</html>
}
file 'app/controllers/application_controller.rb',
%q{class ApplicationController < ActionController::Base
before_filter :create_navigation
filter_parameter_logging :password, :password_confirmation
helper_method :current_user_session, :current_user
def index
end
private
def create_navigation
@navigation_items = [
[ 'Home', root_path ]
]
end
def current_user_session
return @current_user_session if defined?(@current_user_session)
@current_user_session = UserSession.find
end
def current_user
return @current_user if defined?(@current_user)
@current_user = current_user_session && current_user_session.user
end
def require_user
unless current_user
store_location
flash[:notice] = "You must be logged in to access this page"
redirect_to new_user_session_url
return false
end
end
def require_no_user
if current_user
store_location
flash[:notice] = "You must be logged out to access this page"
redirect_to account_url
return false
end
end
def store_location
session[:return_to] = request.request_uri
end
def redirect_back_or_default(default)
redirect_to(session[:return_to] || default)
session[:return_to] = nil
end
def authenticate
unless current_user_session
redirect_to login_path
end
end
end
}
# -- User Sessions (logins)
file 'app/controllers/user_sessions_controller.rb',
%q{class UserSessionsController < ApplicationController
before_filter :require_no_user, :only => [:new, :create]
before_filter :require_user, :only => :destroy
def new
@user_session = UserSession.new
end
def create
@user_session = UserSession.new(params[:user_session])
if @user_session.save
flash[:notice] = "Login successful!"
redirect_back_or_default account_url
else
render :action => :new
end
end
def destroy
current_user_session.destroy
flash[:notice] = "Logout successful!"
redirect_back_or_default new_user_session_url
end
end
}
file 'app/views/user_sessions/new.html.erb',
%q{<% form_for @user_session, :url => user_session_path do |f| %>
<fieldset>
<legend>Log In</legend>
<%= f.error_messages %>
<p>
<%= f.label :email %><br />
<%= f.text_field :email %>
</p>
<p>
<%= f.label :password %><br />
<%= f.password_field :password %>
</p>
<p><%= link_to "Forgot your password?", new_password_reset_path %></p>
<p><%= f.check_box :remember_me %><%= f.label :remember_me %></p>
</fieldset>
<p><%= f.submit "Login" %></p>
<% end %>
}
file 'app/controllers/users_controller.rb',
%q{class UsersController < ApplicationController
before_filter :require_no_user, :only => [:new, :create]
before_filter :require_user, :only => [:show, :edit, :update]
def new
@user = User.new
end
def create
@user = User.new(params[:user])
if @user.save
flash[:notice] = "Account registered!"
redirect_back_or_default account_url
else
render :action => :new
end
end
def show
@user = @current_user
end
def edit
@user = @current_user
end
def update
@user = @current_user # makes our views "cleaner" and more consistent
if @user.update_attributes(params[:user])
flash[:notice] = "Account updated!"
redirect_to account_url
else
render :action => :edit
end
end
end
}
# --- Users ---
file 'app/models/user.rb',
%q{class User < ActiveRecord::Base
acts_as_authentic
acts_as_authorized_user
acts_as_authorizable
def deliver_password_reset_instructions!
reset_perishable_token!
Notifier.deliver_password_reset_instructions(self)
end
end
}
file 'app/views/users/_form.html.erb',
%q{<% form_for @user, :url => account_path do |f| %>
<%= f.error_messages %>
<fieldset>
<p>
<%= f.label :display_name %><br />
<%= f.text_field :display_name %>
</p>
<p>
<%= f.label :email %><br />
<%= f.text_field :email %>
</p>
<p>
<%= f.label :password, form.object.new_record? ? nil : "Change password" %><br />
<%= f.password_field :password %>
</p>
<p>
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %>
</p>
<%= f.submit "Submit" %>
<% end -%>
}
file 'app/views/users/new.html.erb',
%q{<h1>Register</h1>
<%= render :partial => "form" %>
}
file 'app/views/users/edit.html.erb',
%q{<h1>Edit My Account</h1>
<%= render :partial => "form" %>
<p><%= link_to "My Profile", account_path %></p>
}
file 'app/views/users/show.html.erb',
%q{
<h1>
<%=h @user.display_name %>
</h1>
<p>
<b>Login count:</b>
<%=h @user.login_count %>
</p>
<p>
<b>Last request at:</b>
<%=h @user.last_request_at %>
</p>
<p>
<b>Last login at:</b>
<%=h @user.last_login_at %>
</p>
<p>
<b>Current login at:</b>
<%=h @user.current_login_at %>
</p>
<p>
<b>Last login ip:</b>
<%=h @user.last_login_ip %>
</p>
<p>
<b>Current login ip:</b>
<%=h @user.current_login_ip %>
</p>
<%= link_to 'Edit', edit_account_path %>
}
# --- Mailers ---
file 'app/models/notifier.rb',
%q{class Notifier < ActionMailer::Base
default_url_options[:host] = "example.com"
def password_reset_instructions(user)
subject "Password Reset Instructions"
from "Example Notifier "
recipients user.email
sent_on Time.now
body :edit_password_reset_url => edit_password_reset_url(user.perishable_token)
end
end
}
file 'app/views/notifier/password_reset_instructions.erb',
%q{A request to reset your password has been made.
If you did not make this request, simply ignore this email. If you did make this request just click the link below:
<%= @edit_password_reset_url %>
If the above URL does not work try copying and pasting it into your browser. If you continue to have problem please feel free to contact us.
}
# this file is generated by the rails_authorization_plugin, but need to add the "help postgres" lines
file 'app/models/roles_user.rb',
%q{class RolesUser < ActiveRecord::Base
belongs_to :user
belongs_to :role
# help postgres
set_primary_key :user_id
set_primary_key :role_id
end
}
file 'public/stylesheets/screen.css',
%q{/*
Copyright
*/
/*\*/
@import url("reset.css");
@import url("typography.css");
/**/
}
file 'public/stylesheets/typography.css',
%q{/*
Copyright
*/
html {
font-size:100.01%;
}
body {
background:#FFF;
color:#333;
font-family:"helvetica neue",helvetica,arial,sans-serif;
font-size:0.96em; /* IE6 equiv to pixel setting below */
line-height:1.4;
}
html>body {
font-size:18px;
}
a:link,
a:visited {
color:#333;
text-decoration:none;
}
a:hover {
color:#555;
text-decoration:none;
}
a:active {
color:#111;
text-decoration:none;
}
a.buttonish {
font-weight:bold;
font-size:80%;
padding:5px 10px;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
}
a.buttonish:link,
a.buttonish:visited {
color:#333;
background:#999;
}
a.buttonish:hover {
color:#DDD;
background:#555;
}
a.buttonish:active {
color:#DDD;
background:#333;
}
}
file 'public/stylesheets/reset.css',
%q{/*
Reset styles via http://meyerweb.com/eric/thoughts/2007/05/01/reset-reloaded/
Copyright 1995-2007 Eric A. and Kathryn S. Meyer
*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, font, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td {
margin: 0;
padding: 0;
border: 0;
outline: 0;
font-weight: inherit;
font-style: inherit;
font-size: 100%;
font-family: inherit;
vertical-align: baseline;
}
address {
font-style:normal; /* IE6 doesn't get the picture in the first rule */
}
/* remember to define focus styles! */
:focus {
outline: 0;
}
body {
line-height: 1;
color: black;
background: white;
}
ol, ul {
list-style: none;
}
/* tables still need 'cellspacing="0"' in the markup */
table {
border-collapse: separate;
border-spacing: 0;
}
caption, th, td {
text-align: left;
font-weight: normal;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: "";
}
blockquote, q {
quotes: "" "";
}
}
#======================
# INITIALIZERS
#----------------------
initializer 'action_mailer_configs.rb',
%q{#ActionMailer::Base.smtp_settings = {
# :address => "smtp.opb.org",
# :port => 25,
# :domain => "opb.org"
#}
}
initializer 'errors.rb',
%q{# Example:
# begin
# some http call
# rescue *HTTP_ERRORS => error
# notify_hoptoad error
# end
HTTP_ERRORS = [Timeout::Error,
Errno::EINVAL,
Errno::ECONNRESET,
EOFError,
Net::HTTPBadResponse,
Net::HTTPHeaderSyntaxError,
Net::ProtocolError]
# SMTP_SERVER_ERRORS = [TimeoutError,
# IOError,
# Net::SMTPUnknownError,
# Net::SMTPServerBusy,
# Net::SMTPAuthenticationError]
#
# SMTP_CLIENT_ERRORS = [Net::SMTPFatalError,
# Net::SMTPSyntaxError]
#
# SMTP_ERRORS = SMTP_SERVER_ERRORS + SMTP_CLIENT_ERRORS
}
initializer 'time_formats.rb',
%q{# Example time formats
{ :short_date => "%x", :long_date => "%a, %b %d, %Y" }.each do |k, v|
ActiveSupport::CoreExtensions::Time::Conversions::DATE_FORMATS.update(k => v)
end
}
#======================
# TEST
#----------------------
inside ('test') do
run "mkdir factories"
end
file 'test/shoulda_macros/forms.rb',
%q{class Test::Unit::TestCase
def self.should_have_form(opts)
model = self.name.gsub(/ControllerTest$/, '').singularize.downcase
model = model[model.rindex('::')+2..model.size] if model.include?('::')
http_method, hidden_http_method = form_http_method opts[:method]
should "have a #{model} form" do
assert_select "form[action=?][method=#{http_method}]", eval(opts[:action]) do
if hidden_http_method
assert_select "input[type=hidden][name=_method][value=#{hidden_http_method}]"
end
opts[:fields].each do |attribute, type|
attribute = attribute.is_a?(Symbol) ? "#{model}[#{attribute.to_s}]" : attribute
assert_select "input[type=#{type.to_s}][name=?]", attribute
end
assert_select "input[type=submit]"
end
end
end
def self.form_http_method(http_method)
http_method = http_method.nil? ? 'post' : http_method.to_s
if http_method == "post" || http_method == "get"
return http_method, nil
else
return "post", http_method
end
end
end
}
file 'test/shoulda_macros/pagination.rb',
%q{class Test::Unit::TestCase
# Example:
# context "a GET to index logged in as admin" do
# setup do
# login_as_admin
# get :index
# end
# should_paginate_collection :users
# should_display_pagination
# end
def self.should_paginate_collection(collection_name)
should "paginate #{collection_name}" do
assert collection = assigns(collection_name),
"Controller isn't assigning to @#{collection_name.to_s}."
assert_kind_of WillPaginate::Collection, collection,
"@#{collection_name.to_s} isn't a WillPaginate collection."
end
end
def self.should_display_pagination
should "display pagination" do
assert_select "div.pagination", { :minimum => 1 },
"View isn't displaying pagination. Add <%= will_paginate @collection %>."
end
end
# Example:
# context "a GET to index not logged in as admin" do
# setup { get :index }
# should_not_paginate_collection :users
# should_not_display_pagination
# end
def self.should_not_paginate_collection(collection_name)
should "not paginate #{collection_name}" do
assert collection = assigns(collection_name),
"Controller isn't assigning to @#{collection_name.to_s}."
assert_not_equal WillPaginate::Collection, collection.class,
"@#{collection_name.to_s} is a WillPaginate collection."
end
end
def self.should_not_display_pagination
should "not display pagination" do
assert_select "div.pagination", { :count => 0 },
"View is displaying pagination. Check your logic."
end
end
end
}
file 'test/test_helper.rb',
%q{ENV["RAILS_ENV"] = "test"
require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
require 'test_help'
require 'action_view/test_case'
class Test::Unit::TestCase
self.use_transactional_fixtures = true
self.use_instantiated_fixtures = false
self.backtrace_silencers << :rails_vendor
self.backtrace_filters << :rails_root
end
class ActionView::TestCase
# Enable UrlWriter when testing helpers
include ActionController::UrlWriter
# Default host for helper tests
default_url_options[:host] = HOST
end
}
#======================
# FINALIZE
#----------------------
run "rm public/index.html"
run "rm public/images/rails.png"
run 'find . \( -type d -empty \) -and \( -not -regex ./\.git.* \) -exec touch {}/.gitignore \;'
git :add => "."
git :commit => "-a -m 'Initial project commit'"
puts ""
puts "# Add the following to the top of config/environment.rb:"
puts "# Authorization Plugin config"
puts "AUTHORIZATION_MIXIN = 'object roles'"
puts "LOGIN_REQUIRED_REDIRECTION = '/login'"
puts "PERMISSION_DENIED_REDIRECTION = '/'"
puts "STORE_LOCATION_METHOD = :store_location"
puts ""
puts "run `rake app:bootstrap` to create the admin user"
puts "login: admin@example.com"
puts "passwd: letmein"
puts ""
puts "All done!"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment