Skip to content
Browse files

Updated README

  • Loading branch information...
1 parent 0ca34ee commit 601bbfbcd5ef3a06ce9012ce6138a42e744c0b66 @fortuity committed
Showing with 58 additions and 1,169 deletions.
  1. +11 −1,168 README
  2. +47 −1 README.markdown
View
1,179 README
@@ -1,1185 +1,28 @@
Subdomain-Authentication
+========================
-You can use this project as a starting point for any Rails web application that requires subdomains and authentication. User management and authentication is implemented using "Devise":http://github.com/plataformatec/devise. The "subdomain_routes":http://github.com/mholling/subdomain_routes/ gem implements subdomains and routing.
+You can use this project as a starting point for any Rails web application that requires subdomains and authentication. User management and authentication is implemented using the Devise gem (http://github.com/plataformatec/devise). The subdomain_routes gem (http://github.com/mholling/subdomain_routes/) implements subdomains and routing.
+________________________
Tutorial
A complete "walkthrough" tutorial is available on the GitHub wiki:
-[Tutorial](http://wiki.github.com/fortuity/subdomain-authentication/)
+http://wiki.github.com/fortuity/subdomain-authentication/tutorial-walkthrough
-This tutorial documents each step that you must follow to create this application.
+________________________
-Use Cases
+See the README file on GitHub
-1) Administrators can visit the "admin" subdomain and view an administrative home page.
-2) Visitors to the main application (without a subdomain) can register as users and create subdomains.
-3) Any visitor can visit a subdomain and see a "site" home page.
+For more information, please see the updated README file on GitHub:
-Assumptions
+http://github.com/fortuity/subdomain-authentication
-This tutorial is based on Rails version 2.3.5. Some of the code shown here will not work in older versions of Rails.
-
-This was written before the release of Rails 3.0. Things will change significantly in Rails 3.0 so this tutorial will be outdated when Rails 3.0 is released.
-
-Before beginning this tutorial, you need to install
-
-* The Ruby language ruby (version 1.8.7 or newer)
-* The RubyGems packaging system (version 1.3.5 or newer)
-* A working installation of SQLite (preferred), MySQL, or PostgreSQL
-* Rails (version 2.3.5 or newer)
-
-Check that current versions are installed on your computer:
-
-ruby -v
-gem -v
-rails -v
-
-You should have experience building a simple Rails application. Refer to http://guides.rubyonrails.org/ (Rails Guides) for help if you are a beginner.
-
-Create the Rails Application
-
-Open a terminal, navigate to a folder where you have rights to create files, and type:
-
-$ rails subdomain-authentication
-
-You may give the app a different name if you are building it for your own use. For this tutorial, we'll assume the name is "subdomain-authentication."
-
-This will create a Rails application that uses a SQLite database for data storage. You may also use MySQL or PostgreSQL for data storage (refer to http://guides.rubyonrails.org/getting_started.html (Getting Started with Rails)).
-
-After you create the application, switch to its folder to continue work directly in that application:
-
-$ cd subdomain-authentication
-
-Edit the README file to remove the standard Rails boilerplate. Add what you like (at least the name of the app).
-
-Set Up Source Control (Git)
-
-If you're creating an app for deployment into production, you'll want to set up a source control repository at this point. If you are building a throw-away app for your own education, you may skip this step.
-
-Check that git is installed on your computer:
-
-git version
-
-Create a top, project-level .gitignore file containing:
-
-.DS_Store
-log/*.log
-tmp/**/*
-config/database.yml
-config/initializers/site_keys.rb
-db/*.sqlite3
-
-Initialize git and check in your first commit:
-
-git init
-git add .
-git commit -m 'initial commit'
-
-You can check your commit status at any time with:
-
-git status
-
-At this point you can check your local project into a remote source control repository. We'll assume you are using git with an account at GitHub.
-
-Check that your GitHub account is set up properly:
-
-ssh git@github.com
-
-Go to GitHub and create a new empty repository into which you can push your local git repo:
-
-http://github.com/repositories/new
-
-Add GitHub as a remote repository for your project and push your local project to the remote repository:
-
-git remote add origin git@github.com:YOUR_GITHUB_ACCOUNT/YOUR_PROJECT_NAME.git
-git push origin master
-
-At each stage of completion, you should check your code into your local repository:
-
-git commit -a -m "some helpful comment"
-
-and then push it to the remote repository:
-
-git push origin master
-
-Required Gems
-
-The application uses the following gems:
-
-haml (version 2.2.17)
-will_paginate (version 2.3.12)
-formtastic (version 0.9.7)
-warden (version 0.9.3)
-devise (version 1.0.1)
-inherited_resources (version 1.0.3)
-subdomain_routes (version 0.3.1))
-friendly_id (version 2.2.7)
-
-Note that the devise gem must be version 1.0.1 (and the warden gem must be version 0.9.3 to match). Newer versions of this gem only support Rails 3 and are NOT backward compatible. The instructions below force your app to use the correct version of this gem.
-
-Note that the inherited_resources gem must be version 1.0.3. A newer version of the inherited_resources gem (version 1.1.0) only supports Rails 3 and is NOT backward compatible. The instructions below force your app to use inherited_resources version 1.0.3 and not the newer version. If you launch the app and get the error
-
-uninitialized constant Rails::Railtie
-
-you are using a newer version of the inherited_resources gem.
-
-Install Gems
-
-You can check which gems are installed on your computer with:
-
-gem list --local
-
-If any gems need updating, you can update all with
-
-sudo gem update
-
-or individually, as in this example:
-
-sudo gem update haml
-sudo gem update will_paginate
-sudo gem update formtastic
-sudo gem update devise
-sudo gem update warden
-sudo gem update inherited_resources
-sudo gem update subdomain_routes
-sudo gem update friendly_id
-
-If they are not already installed, install the required gems on your computer:
-
-sudo gem install haml
-sudo gem install will_paginate
-sudo gem install formtastic
-sudo gem install warden --version=0.9.3
-sudo gem install devise --version=1.0.1
-sudo gem install inherited_resources --version=1.0.3
-sudo gem install subdomain_routes
-sudo gem install friendly_id
-
-Keep in mind that you have installed these gems locally. When you deploy the app to another server, the same gems (and versions) must be available.
-
-Specify the Required Gems
-
-Modify the environment.rb file to specify the required gems:
-
-# Specifies gem version of Rails to use when vendor/rails is not present
-RAILS_GEM_VERSION = '2.3.4' unless defined? RAILS_GEM_VERSION
-
-# Bootstrap the Rails environment, frameworks, and default configuration
-require File.join(File.dirname(__FILE__), 'boot')
-
-Rails::Initializer.run do |config|
- config.gem 'haml', :lib => 'haml', :version => '>=2.2.17'
- config.gem 'will_paginate', :source => 'http://gemcutter.org', :version => '>= 2.3.12'
- config.gem 'formtastic', :source => 'http://gemcutter.org/', :version => '>= 0.9.7'
- config.gem 'devise', :source => 'http://gemcutter.org/', :version => '>= 0.9.1'
- config.gem 'warden', :source => 'http://gemcutter.org/', :version => '>= 0.9.0'
- config.gem "inherited_resources", :lib => "inherited_resources", :source => "http://gemcutter.org/",:version => '1.0.3'
- config.gem "subdomain_routes", :source => "http://gemcutter.org", :version => '>= 0.3.1'
- config.gem 'friendly_id', :version => '>= 2.2.7'
-
- config.time_zone = 'UTC'
-end
-
-Create a Gems Manifest for Heroku
-
-If you're going to be deploying your app to the Heroku hosted platform, this is an opportune time to create a gems manifest for Heroku. If you do not intend to deploy to Heroku, you can skip this step.
-
-Create a top, project-level .gems file containing:
-
-haml --version '>= 2.2.17'
-will_paginate --version '>= 2.3.12' --source http://gemcutter.org
-formtastic --version '>= 0.9.7' --source http://gemcutter.org
-devise --version '>= 0.9.1' --source http://gemcutter.org
-warden --version '>= 0.9.0' --source http://gemcutter.org
-inherited_resources --version '1.0.3' --source http://gemcutter.org
-subdomain_routes --version '>= 0.3.1' --source http://gemcutter.org
-friendly_id --version '>= 2.2.7'
-
-Install Gems for Development
-
-The following gems are not needed for the application to run but they will be used during development. Install them now if they are not already installed:
-
-sudo gem install nifty-generators
-sudo gem install dry_scaffold
-
-Enable Haml
-
-To enable Haml for the application, run:
-
-haml --rails .
-
-(Be sure to include the trailing dot to specify the path to the current directory.)
-
-This will create a Haml plugin in "vendor/plugins". After Haml is initialized, all view files with the ".html.haml" extension will be compiled using Haml when the application is launched.
-
-Create an Application Layout
-
-Create application layout, stylesheet, and helper files.
-
-script/generate nifty_layout --haml
-
-This will create the default layout for every page in the application:
-
-app/views/layouts/application.html.haml
-
-As well as a layout helper file with helper methods for page title and stylesheet includes:
-
-app/helpers/layout_helper.rb
-
-and an initial SASS format stylesheet file:
-
-public/stylesheets/sass/application.sass
-
-Modify the Application SASS Stylesheet
-
-Current Rails practice is to use "flash_notice" and "flash_alert" as the CSS identifiers for application messages. The SASS application stylesheet file generated by nifty_layout uses "flash_error" instead of "flash_alert". You'll need to change the file:
-
-public/stylesheets/sass/application.sass
-
-replacing "flash_error" with "flash_alert".
-
-Add Stylesheets
-
-You might wait until after you've built your application to begin applying CSS styling to your pages. Or you can do it now and your pages will look more visually appealing during development.
-
-This application uses HAML and its companion SASS to to mark up pages for layout and CSS styling. We also use the formtastic gem in conjunction with a SASS version of formtastic to mark up forms. The SASS version of formtastic is available here: http://github.com/activestylus/formtastic-sass.
-
-In the directory for the SASS files:
-
-public/stylesheets/sass
-
-add SASS stylesheet files for formtastic styling:
-
-http://github.com/activestylus/formtastic-sass/blob/master/_formtastic_base.sass
-http://github.com/activestylus/formtastic-sass/blob/master/_skintastic.sass
-http://github.com/activestylus/test_formtastic_sass/blob/master/public/stylesheets/sass/_scaffold.sass
-
-Modify the application SASS file to import the formtastic SASS files:
-
-public/stylesheets/sass/application.sass
-
-Add this at the beginning of the application SASS file:
-
-@import scaffold.sass
-@import formtastic_base.sass
-@import skintastic.sass
-
-As you develop your app, you can refer to http://github.com/activestylus/formtastic-sass for instructions on modifying the styling of forms.
-
-When you launch your web app, HAML will automatically generate an application.css file from the component SASS files.
-
-Create a Home Page
-
-Create the first page of the application. Use the Rails generate command to create a "home" controller and a "views/home/index" page.
-
-script/generate controller home index
-
-There's no option in Rails 2.3.4 to generate Haml instead of erb view files, so you will have to delete:
-
-app/views/home/index.html.erb
-
-and add:
-
-app/views/home/index.html.haml
-
-containing only:
-
-- title 'Subdomain-Authentication'
-
-Now, you have to set a route to your home page. Edit the file config/routes.rb and add:
-
-map.root :controller => "home"
-
-Remove the index.html File
-
-Delete the default page from your application:
-
-$ rm public/index.html
-
-While you are here, you may also want to modify the file public/robots.txt to prevent indexing by search engines if you plan to have a development version on a publicly accessible server:
-
-# To ban all spiders from the entire site uncomment the next two lines:
-User-Agent: *
-Disallow: /
-
-Test the App
-
-You can check that your app runs properly by entering the command
-
-script/server
-
-To see your application in action, open a browser window and navigate to http://localhost:3000. You should see the Rails default information page.
-
-Stop the server with Control-C.
-
-Set Up Configuration for Devise
-
-This app uses Devise for user management and authentication. Devise is at http://github.com/plataformatec/devise.
-
-We've already installed the Devise gem. Run the generator:
-
-script/generate devise_install
-
-which installs a configuration file:
-
-config/initializers/devise.rb
-
-and a localization file.
-
-Set up action_mailer in your development environment in the file
-
-config/environments/development.rb
-
-by changing:
-
-# Don't care if the mailer can't send
-# config.action_mailer.raise_delivery_errors = false
-
-and adding:
-
-### ActionMailer Config
-config.action_mailer.default_url_options = { :host => 'localhost:3000' }
-# A dummy setup for development - no deliveries, but logged
-config.action_mailer.delivery_method = :smtp
-config.action_mailer.perform_deliveries = false
-config.action_mailer.raise_delivery_errors = true
-config.action_mailer.default_charset = "utf-8"
-
-Set up action_mailer in your production environment in the file
-
-config/environments/production.rb
-
-by adding:
-
-config.action_mailer.default_url_options = { :host => 'yourhost.com' }
-### ActionMailer Config
-# Setup for production - deliveries, no errors raised
-config.action_mailer.delivery_method = :smtp
-config.action_mailer.perform_deliveries = true
-config.action_mailer.raise_delivery_errors = false
-config.action_mailer.default_charset = "utf-8"
-
-Generate Models, Migrations, and Routes for Users and Admins
-
-This app manages users and administrators separately, allowing the two roles to be implemented differently.
-
-Use Devise to generate models, migrations, and routes for a User and Admin:
-
-script/generate devise User
-script/generate devise Admin
-
-Add a Name Attribute to User and Admin
-
-By default, Devise uses an email address to identify users. We'll add a name attribute as well.
-
-Modify each migration to add a "name" field to the data table.
-
-Modify the files:
-
-app/models/admin.rb
-app/models/user.rb
-
-and change:
-
- attr_accessible :email, :password, :password_confirmation
-
-to:
-
- attr_accessible :name, :email, :password, :password_confirmation
-
-to allow users and admins to be created (or edited) with a name attribute.
-
-Create Model and Migration for Subdomains
-
-Each user will be able to register and use a subdomain.
-
-Generate a model and migration for Subdomains. Since a Subdomain will belong to a user, the "user:references" parameter adds a field "user_id" to the data table to handle the relationship with a User:
-
-script/generate model Subdomain name:string user:references
-
-Modify the Subdomain model so the URL for accessing a subdomain uses a name instead of a number:
-
-class Subdomain < ActiveRecord::Base
- belongs_to :user
- has_friendly_id :name
- def to_param
- name
- end
-end
-
-Modify the User Model to Have Subdomains
-
-Subdomains belong to users, so we have to set up the User side of the relationship. We'll also modify the User model so the URL for accessing a user uses a name instead of a number:
-
-class User < ActiveRecord::Base
- has_many :subdomains, :dependent => :destroy
- has_friendly_id :name
- # Include default devise modules.
- # Others available are :lockable, :timeoutable and :activatable.
- devise :authenticatable, :confirmable, :recoverable, :rememberable, :trackable, :validatable
-
- # Setup accessible (or protected) attributes for your model
- attr_accessible :name, :email, :password, :password_confirmation
-end
-
-Create a Site Model
-
-We'll create a Site model as a subclass of the Subdomain model so that each user can view a site at their subdomain. The Site is a simple stub in this application. It can be customized for additional functionality (for example, implementation as a blog).
-
-The Site model is very simple so there's no need to use a generator:
-
-class Site < Subdomain
-end
-
-Create a Database and Run Migrations
-
-Now create an empty database. You can do this by running a rake command:
-
-rake db:create
-
-Run the migrations:
-
-rake db:migrate
-
-You can take a look at the database schema that's been created for you:
-
-db/schema.rb
-
-Add a User and Administrator to the Database
-
-Create a rake file:
-
-touch lib/tasks/setup.rake
-
-with the following code:
-
-namespace :myapp do
-
- desc 'set up subdomain-authentication example with default user and administrator'
- task :setup => ['db:drop', 'db:create', 'db:migrate', 'environment'] do
- puts 'SETTING UP NEW USER AND ADMIN LOGINS'
- puts 'DELETING ANY EXISTING USER AND ADMIN RECORDS'
- user = User.create! do |u|
- u.name = 'firstuser'
- u.email = 'user@test.com'
- u.password = 'user123'
- u.password_confirmation = 'user123'
- end
- user.confirm!
- puts 'New user created!'
-
- admin = Admin.create! do |u|
- u.name = 'admin'
- u.email = 'admin@test.com'
- u.password = 'admin123'
- u.password_confirmation = 'admin123'
- end
- admin.confirm!
- puts 'New admin created!'
-
- subdomain = Subdomain.create! do |s|
- s.user_id = '1'
- s.name = 'test'
- end
- puts 'created subdomain ' << subdomain.name
- end
-end
-
-Run the rake file:
-
-rake myapp:setup
-
-Configure subdomain_routes
-
-Create a configuration file for the subdomain_routes gem:
-
-config/initializers/subdomain_routes.rb
-
-The following configuration is suitable if you are developing the app to run at "localhost" and deploying to a domain such as "example.com". See the information at http://github.com/mholling/subdomain_routes/ if your development or deployment is different.
-
-if Rails.env.to_sym == :development
- require 'subdomain_routes'
- # make sure subdomain_routes can handle a nil subdomain:
- # http://code.matthewhollingworth.net/articles/2009-06-02-adding-subdomains-to-rails-routing
- SubdomainRoutes::Config.domain_length = 1
-end
-if Rails.env.to_sym == :production
- require 'subdomain_routes'
- # make sure subdomain_routes can handle a nil subdomain:
- # http://code.matthewhollingworth.net/articles/2009-06-02-adding-subdomains-to-rails-routing
- SubdomainRoutes::Config.domain_length = 2
-end
-
-Modify the Application Controller
-
-We don't want passwords written to our log file. Change the file
-
-app/controllers/application_controller.rb
-
-to include:
-
-filter_parameter_logging :password, :password_confirmation
-
-Create a Controller and View for an Administrative Home Page
-
-We want administrators to visit the "admin" subdomain and view an administrative home page.
-
-Create a controller for an administrative home page:
-
-touch app/controllers/admin_home_controller.rb
-
-with the following code:
-
-class AdminHomeController < ApplicationController
- before_filter :authenticate_admin!
- def index
- end
-end
-
-Create a view for an administrative home page:
-
-mkdir app/views/admin_home/
-touch app/views/admin_home/index.html.haml
-
-with the following code:
-
-- title 'Admin Home'
-%p
- Welcome to the Admin section of the application.
-= link_to "View List of Admins", admin_admins_path
-
-Add the following routes to implement this use case. Edit the file config/routes.rb and add:
-
-map.subdomain :admin do |admin|
- admin.root :controller => "adminhome"
-end
-
-If you launch the application and visit
-http://admin.localhost:3000/
-you'll be prompted to sign in as an administrator.
-
-Sign in as "admin@test.com" with password "admin123". You'll see an error page because we haven't set up routing, controller and views to implement a link to "View List of Admins".
-
-Create a Controller and Views to Manage Administrators
-
-We want to view a list of administrators when we log in as an administrator at the "admin" subdomain. We also want to allow administrators to edit, delete, and add new administrators.
-
-Create a controller to manage administrators:
-
-touch app/controllers/admins_controller.rb
-
-with the following code:
-
-class AdminsController < InheritedResources::Base
- actions :index, :show, :new, :edit, :create, :update, :destroy
- respond_to :html, :js, :xml, :json
- before_filter :authenticate_admin!
-
- protected
-
- def collection
- paginate_options ||= {}
- paginate_options[:page] ||= (params[:page] || 1)
- paginate_options[:per_page] ||= (params[:per_page] || 20)
- @admins ||= end_of_association_chain.paginate(paginate_options)
- end
-
-end
-
-Create views to manage administrators:
-
-mkdir app/views/admins/
-touch app/views/admins/_form.html.haml
-touch app/views/admins/_item.html.haml
-touch app/views/admins/edit.html.haml
-touch app/views/admins/index.html.haml
-touch app/views/admins/new.html.haml
-touch app/views/admins/show.html.haml
-
-Add the following code to each file:
-
-app/views/admins/_form.html.haml
-
-- form.inputs do
- = form.input :name, :label => 'Name'
- = form.input :email, :label => 'Email'
- = form.input :password, :label => 'Password'
-
-app/views/admins/_item.html.haml
-
-- content_tag_for(:tr, admin, :class => cycle(:odd, :even)) do
- %td.name= h admin.try(:name)
- %td.actions
- = link_to 'Show', admin_admin_path(admin)
- |
- = link_to 'Edit', edit_admin_admin_path(admin)
- |
- = link_to 'Destroy', admin_admin_url(admin), :confirm => 'Are you sure?', :method => :delete
-
-app/views/admins/edit.html.haml
-
-%h1.heading
- = "Editing admin %s" % @admin.id
-
-- semantic_form_for(@admin, :url => { :controller => 'admins', :action => 'update' }) do |form|
- = render 'form', :form => form
- - form.buttons do
- = form.commit_button 'Update'
-
-%p.actions
- = link_to 'Cancel', admin_admins_path
-
-app/views/admins/index.html.haml
-
-%h1.heading
- = "Admins"
-
-%p.actions
- = link_to 'New Admin', new_admin_admin_path
-
-%table
- %thead.header
- %tr
- %th.name= 'Name'
- %th.actions= 'Actions'
- %tbody.items.admins
- - @admins.each do |admin|
- = render 'item', :admin => admin
-
-= will_paginate(@admins)
-
-app/views/admins/new.html.haml
-
-%h1.heading
- = 'New Admin'
-
-- semantic_form_for(@admin, :url => { :controller => 'admins', :action => 'create' }) do |form|
- = render 'form', :form => form
- - form.buttons do
- = form.commit_button 'Create'
-
-%p.actions
- = link_to 'Cancel', admin_admins_path
-
-app/views/admins/show.html.haml
-
-%h1.heading
- = "Admin %s" % @admin.id
-
-- content_tag_for(:dl, @admin) do
- %dt.label= 'Name'
- %dd.name= h @admin.try(:name)
- %dt.label= 'Email'
- %dd.name= h @admin.try(:email)
-
-%p.actions
- = link_to 'Edit', edit_admin_admin_path(@admin)
- |
- = link_to 'List of Admins', admin_admins_path
-
-
-Implement Routing for Administrators
-
-Modify the following routes to implement this use case:
-
-map.subdomain :admin do |admin|
- admin.root :controller => "AdminHome"
- admin.resources :admins
-end
-
-Now you can sign in as "admin@test.com" with password "admin123". You can "View List of Admins" and edit, delete, and add new administrators.
-
-Create a Controller and Views to Manage Users
-
-The site's home page has no subdomain. We have a home page for the app but we want to add a link to a page that shows a list of users. We want any visitor to be able to register as a user. We want any logged-in user to be able to edit or delete his or her own record (but no one else's).
-
-Create a controller to manage users:
-
-touch app/controllers/users_controller.rb
-
-with the following code:
-
-class UsersController < InheritedResources::Base
-
- actions :index, :show, :new, :edit, :create, :update, :destroy
- respond_to :html, :js, :xml, :json
- before_filter :find_user, :only => [:edit, :update, :destroy]
-
- protected
-
- def collection
- paginate_options ||= {}
- paginate_options[:page] ||= (params[:page] || 1)
- paginate_options[:per_page] ||= (params[:per_page] || 20)
- @users ||= end_of_association_chain.paginate(paginate_options)
- end
-
- def find_user
- @user = User.find(params[:id])
- unless current_user == @user
- flash[:alert] = "You are not allowed to make changes to someone else's account."
- redirect_to user_path(@user)
- end
- end
-end
-
-Create views to manage users:
-
-mkdir app/views/users/
-touch app/views/users/_form.html.haml
-touch app/views/users/_item.html.haml
-touch app/views/users/edit.html.haml
-touch app/views/users/index.html.haml
-touch app/views/users/new.html.haml
-touch app/views/users/show.html.haml
-
-Add the following code to each file:
-
-app/views/users/_form.html.haml
-
-- form.inputs do
- = form.input :name, :label => 'Name'
- = form.input :email, :label => 'Email'
- = form.input :password, :label => 'Password'
- = form.input :password_confirmation, :label => 'Password Confirmation'
-
-app/views/users/_item.html.haml
-
-- content_tag_for(:tr, user, :class => cycle(:odd, :even)) do
- %td.name=link_to user.name, user_path(user)
- %td.actions
- = link_to 'Edit', edit_user_path(user)
- |
- = link_to 'Destroy', user, :confirm => 'Are you sure?', :method => :delete
-
-app/views/users/edit.html.haml
-
-%h1.heading
- = "Editing user %s" % @user.id
-
-- semantic_form_for(@user) do |form|
- = render 'form', :form => form
- - form.buttons do
- = form.commit_button 'Update'
-
-%p.actions
- = link_to 'Cancel', users_path
-
-app/views/users/index.html.haml
-
-%h1.heading
- = "Users"
-
-%table
- %thead.header
- %tr
- %th.name= 'Name'
- %th.actions= 'Actions'
- %tbody.items.users
- - @users.each do |user|
- = render 'item', :user => user
-
-= will_paginate(@users)
-
-app/views/users/new.html.haml
-
-%h1.heading
- = 'New User'
-
-- semantic_form_for(@user) do |form|
- = render 'form', :form => form
- - form.buttons do
- = form.commit_button 'Create'
-
-%p.actions
- = link_to 'Cancel', users_path
-
-app/views/users/show.html.haml
-
-%h1.heading
- = "User %s" % @user.id
-
-- content_tag_for(:dl, @user) do
- %dt.label= 'Name'
- %dd.name= h @user.try(:name)
-
-%p.actions
- = link_to 'Edit', edit_user_path(@user)
- |
- = link_to 'List of Users', users_path
-
-Implement Routing for Users
-
-Add the following routes to implement this use case:
-
-map.subdomain nil do |main|
- main.root :controller => "home"
- main.resources :users
-end
-
-Add a Link to the Application Home Page
-
-We want a link to a list of users on the application home page.
-
-Modify the file:
-
-app/views/home/index.html.haml
-
-with these changes:
-
-- title 'Subdomain-Authentication'
-%p
- This is my new app.
-= link_to "View List of Users", users_path
-
-Add Navigation Links to the Application Layout
-
-We want links to sign up, log in, etc. on each page of the application.
-
-Modify the file:
-
-app/views/layouts/application.html.haml
-
-with these changes:
-
-!!! Strict
-%html{html_attrs}
-
- %head
- %title
- = h(yield(:title) || "Untitled")
- %meta{"http-equiv"=>"Content-Type", :content=>"text/html; charset=utf-8"}/
- = stylesheet_link_tag 'application'
- = yield(:head)
-
- %body
- #container
- #navigation
- - if user_signed_in?
- = link_to "Home", root_path
- |
- = link_to 'My Account', user_path(current_user)
- |
- = link_to 'Sign out', destroy_user_session_path
- - if admin_signed_in?
- = link_to 'Admin Home', admin_root_path
- |
- = link_to 'Sign out', destroy_admin_session_path
- - if !user_signed_in? && !admin_signed_in?
- = link_to "Home", root_path
- |
- = link_to 'Register', new_user_path
- |
- = link_to 'Admin Login', admin_root_path
- |
- = link_to 'User Login', new_user_session_path
-
- - flash.each do |name, msg|
- = content_tag :div, msg, :id => "flash_#{name}"
- #content
- - if show_title?
- %h1=h yield(:title)
-
- = yield
-
-Test Sign Up
-
-If you launch the application and visit
-http://admin.localhost:3000/
-you can click a link to register as a new user. The app is configured to require a new user to confirm registration by clicking a link in an email message. The app's development environment is set up to log email messages instead of attempting to send them. Check your console or log file for a log entry that contains the text of the email message with the URL you can use to confirm the new user.
-
-It will look something like this:
-http://localhost:3000/users/confirmation?confirmation_token=b7iljFz77_3Sp6CftdFa
-
-Visit the confimation URL in your web browser to complete registration of a new user.
-
-Create a Controller and Views to Manage Subdomains
-
-Our use case specifies that each registered user can create any number of subdomains which will be hosts for the user's "sites." This app does not provide any functionality for a user's "sites," but you can add functionality so each user can have a blog or other features for their "site."
-
-Create a controller to manage subdomains:
-
-touch app/controllers/subdomains_controller.rb
-
-with the following code:
-
-class SubdomainsController < InheritedResources::Base
- belongs_to :user
-
- actions :index, :show, :new, :edit, :create, :update, :destroy
- respond_to :html, :js, :xml, :json
- before_filter :find_user, :only => [:new, :edit, :create, :update, :destroy]
-
- def create
- create!{ user_url(@user) }
- end
-
- def destroy
- destroy!{ user_url(@user) }
- end
-
- protected
-
- def collection
- paginate_options ||= {}
- paginate_options[:page] ||= (params[:page] || 1)
- paginate_options[:per_page] ||= (params[:per_page] || 20)
- @subdomains ||= end_of_association_chain.paginate(paginate_options)
- end
-
- def find_user
- @user = User.find(params[:user_id])
- unless current_user == @user
- flash[:alert] = "You are not allowed to create or change someone else's subdomain."
- redirect_to user_path(@user)
- end
- end
-
-end
-
-Create views to manage subdomains:
-
-mkdir app/views/subdomains/
-touch app/views/subdomains/_form.html.haml
-touch app/views/subdomains/_item.html.haml
-touch app/views/subdomains/index.html.haml
-touch app/views/subdomains/new.html.haml
-
-Add the following code to each file:
-
-app/views/subdomains/_form.html.haml
-
-- form.inputs do
- = form.input :name, :label => 'Name'
- = form.input :user_id, :as => :hidden
-
-app/views/subdomains/_item.html.haml
-
-- content_tag_for(:tr, subdomain, :class => cycle(:odd, :even)) do
- %td.name= h subdomain.try(:name)
- %td.user_id= link_to subdomain.user.name, user_url(subdomain.user)
- %td.actions
- = link_to 'Destroy', user_subdomain_url(subdomain.user,subdomain), :confirm => 'Are you sure?', :method => :delete
-
-app/views/subdomains/index.html.haml
-
-%h1.heading
- = "Subdomains"
-
-%table
- %thead.header
- %tr
- %th.name= 'Name'
- %th.user_id= 'User'
- %th.actions= 'Actions'
- %tbody.items.subdomains
- - @subdomains.each do |subdomain|
- = render 'item', :subdomain => subdomain
-
-= will_paginate(@subdomains)
-
-app/views/subdomains/new.html.haml
-
-%h1.heading
- = 'New Subdomain'
-
-- semantic_form_for [@user, @subdomain] do |form|
- = render 'form', :form => form
- - form.buttons do
- = form.commit_button 'Create'
-
-%p.actions
- = link_to 'Cancel', user_subdomains_path
-
-Implement Routing for Subdomains
-
-Modify the following routes:
-
-map.subdomain nil do |main|
- main.root :controller => "home"
- main.resources :users do |users|
- users.resources :subdomains, :except => [:edit, :show]
- end
-end
-
-Create a Controller and Views to Display Sites
-
-Each registered user can create any number of subdomains which will be hosts for the user's "sites." This app does not provide any functionality for a user's "sites," but you can add functionality so each user can have a blog or other features for their "site." In this step, we will create a simple stub that displays a "site" page as the home page of any registered subdomain.
-
-Create a controller to manage sites:
-
-touch app/controllers/sites_controller.rb
-
-with the following code:
-
-class SitesController < InheritedResources::Base
-
- actions :index, :show, :new, :edit, :create, :update, :destroy
- respond_to :html, :js, :xml, :json
-
- def show
- @site = Site.find_by_name(params[:site_id])
- show!
- end
-
- protected
-
- def collection
- paginate_options ||= {}
- paginate_options[:page] ||= (params[:page] || 1)
- paginate_options[:per_page] ||= (params[:per_page] || 20)
- @sites ||= end_of_association_chain.paginate(paginate_options)
- end
-
-end
-
-Create views to display sites:
-
-mkdir app/views/sites/
-touch app/views/sites/_item.html.haml
-touch app/views/sites/index.html.haml
-touch app/views/sites/show.html.haml
-
-Add the following code to each file:
-
-app/views/sites/_item.html.haml
-
-- content_tag_for(:tr, site, :class => cycle(:odd, :even)) do
- %td.user_id= link_to site.name, site_site_path(site,site)
- %td.actions
- = link_to site.user.name, user_url(site.user)
-
-app/views/sites/index.html.haml
-
-%h1.heading
- = "Sites"
-
-%table
- %thead.header
- %tr
- %th.actions= 'Site | '
- %th.actions= 'Belongs to'
- %tbody.items.sites
- - @sites.each do |site|
- = render 'item', :site => site
-
-= will_paginate(@sites)
-
-touch app/views/sites/show.html.haml
-
-%h1.heading
- = "Site %s" % @site.id
-%h3.heading
- Subdomain:
- = @site.name
-%h3.heading
- Belongs to:
- = link_to @site.user.name, user_path(@site.user)
-%p.actions
- = link_to 'List of Sites', site_sites_path(@site)
-
-Implement Routing for Sites
-
-Add the following routes to implement this use case:
-
-map.subdomain :model => :site do |site|
- site.root :controller => "sites", :action => "show"
- site.resources :sites, :only => [:index, :show]
-end
-
-Modify the User Views to Include Subdomains
-
-Add a file to implement a "partial" for subdomains:
-
-touch app/views/users/_subdomain_item.html.haml
-
-Add the following code to the file:
-
-- content_tag_for(:tr, subdomain, :class => cycle(:odd, :even)) do
- %td.name= link_to subdomain.name, site_site_path(subdomain,subdomain)
- %td.actions
- = link_to 'Destroy', user_subdomain_url(subdomain.user,subdomain), :confirm => 'Are you sure?', :method => :delete
-
-Edit the file app/views/users/show.html.haml:
-
-%h1.heading
- = "User %s" % @user.id
-
-- content_tag_for(:dl, @user) do
- %dt.label= 'Name'
- %dd.name= h @user.try(:name)
-
-%p.actions
- = link_to 'New Subdomain', new_user_subdomain_path(@user)
-
-%table
- %thead.header
- %tr
- %th.name= 'Subdomains'
- %th.actions= 'Actions'
- %tbody.items.subdomains
- - @user.subdomains.each do |subdomain|
- = render 'subdomain_item', :subdomain => subdomain
-
-%p.actions
- = link_to 'Edit', edit_user_path(@user)
- |
- = link_to 'List of Users', users_path
-
-Test Creating Subdomains
-
-If you launch the application and visit
-http://localhost:3000/
-and login as a user, you can click a link to create a new subdomain.
-
-Deploy to Heroku
-
-For your convenience, here are instructions for deploying your app to Heroku. Heroku provides low cost, easily configured Rails application hosting.
-
-To deploy this app to Heroku, you must have a Heroku account. If you need to obtain one, visit http://heroku.com/ to set up an account. After you set up a Heroku account, install the Heroku gem:
-
-sudo gem install heroku
-
-Add your public key immediately after installing the heroku gem so that you can use git to push or clone Heroku app repositories. See http://docs.heroku.com/heroku-command for details.
-
-Create Your Application on Heroku
-
-Use the Heroku create command to create and name your new app:
-
-heroku create subdomain-authentication
-
-Push your application to Heroku
-
-git push heroku master
-
-Set up your Heroku database:
-
-heroku rake db:migrate
-
-Initialize your application database:
-
-heroku rake myapp:setup
-
-Heroku Add-ons
-
-You will need the following Heroku add-ons to deploy your app using subdomains with your own custom domain:
-
-Custom Domains (free)
-Custom Domains + Wildcard ($5 per month)
-Zerigo DNS (free)
-
-Open your Heroku site in your default web browser:
-
-heroku open
-
-If you get errors, you can troubleshoot by reviewing the log files:
-
-heroku logs
-
-This concludes the tutorial for creating a Ruby on Rails web application that uses subdomains and provides user management and authentication.
+________________________
+Public Domain Dedication
+This work is a compilation and derivation from other previously released works. With the exception of various included works, which may be restricted by other licenses, the author or authors of this code dedicate any and all copyright interest in this code to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this code under copyright law.
View
48 README.markdown
@@ -16,7 +16,7 @@ The tutorial documents each step that you must follow to create this application
2. Visitors to the main application (without a subdomain) can register as users and create subdomains.
3. Any visitor can visit a subdomain and see a "site" home page.
-## Assumptions
+## Dependencies
This application requires Rails version 2.3.5. Some of the code shown here will not work in older versions of Rails.
@@ -28,3 +28,49 @@ To use this application, you need to install
* The RubyGems packaging system (version 1.3.5 or newer)
* A working installation of SQLite (preferred), MySQL, or PostgreSQL
* Rails (version 2.3.5 or newer)
+
+## Gems Required
+
+The application uses the following gems:
+
+* haml (version 2.2.17)
+* will_paginate (version 2.3.12)
+* formtastic (version 0.9.7)
+* warden (version 0.9.3)
+* devise (version 1.0.1)
+* inherited_resources (version 1.0.3)
+* subdomain_routes (version 0.3.1)
+* friendly_id (version 2.2.7)
+
+## Get It
+
+The source code is managed with Git (a version control system) and hosted at GitHub. You'll need Git on your machine (install it from [http://git.or.cz/](http://git.or.cz/)).
+
+You can download the app ("clone the repository") with the command
+
+ $ git@github.com:fortuity/subdomain-authentication.git
+
+## Testing
+
+The application does not include tests (of either Test::Unit or RSpec varieties). It relies on [Devise](http://github.com/plataformatec/devise) which includes extensive tests. This application is intended to be a basis for your own customized application and (in most cases) you will be writing your own tests for your required behavior.
+
+## Documentation and Support
+
+You can find documentation for [Devise](http://github.com/plataformatec/devise) at [http://github.com/plataformatec/devise](http://github.com/plataformatec/devise). There is an active [Devise mailing list](http://groups.google.com/group/plataformatec-devise) and you can submit [Devise issues](http://github.com/plataformatec/devise/issues) at GitHub.
+
+You can find documentation for [subdomain_routes](http://github.com/mholling/subdomain_routes/) at [http://github.com/mholling/subdomain_routes/](http://github.com/mholling/subdomain_routes/). There is no active forum for support but you can post to [Matthew Hollingworth's blog](http://code.matthewhollingworth.net/articles/2009-06-02-adding-subdomains-to-rails-routing) with questions and submit [subdomain_routes issues](http://github.com/mholling/subdomain_routes/issues) at GitHub.
+
+The [Devise](http://github.com/plataformatec/devise) community and [subdomain_routes](http://github.com/mholling/subdomain_routes/) author are your best source for answers to questions about authentication and subdomain implementation. For specific issues with this application, you can submit [bug reports](http://github.com/fortuity/subdomain-authentication/issues) at GitHub. If you want to post complaints (or praise!) about this application, there is a forum for this application at [Get Satisfaction](http://getsatisfaction.com/origin/products/origin_rails_23subdomain_authentication_example_application).
+
+This application is provided without additional documentation or support.
+
+## Credits
+
+Daniel Kehoe ([http://danielkehoe.com/](http://danielkehoe.com/)) implemented the application and wrote the tutorial.
+
+## License
+
+### Public Domain Dedication
+
+This work is a compilation and derivation from other previously released works. With the exception of various included works, which may be restricted by other licenses, the author or authors of this code dedicate any and all copyright interest in this code to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this code under copyright law.
+

0 comments on commit 601bbfb

Please sign in to comment.
Something went wrong with that request. Please try again.