adding devise + create account model and bind it to site

This commit is contained in:
dinedine 2010-04-13 15:24:12 +02:00
parent 0db6b9625f
commit 30789cbbc3
20 changed files with 244 additions and 25 deletions

View File

@ -1,17 +1,23 @@
class Account class Account
include Mongoid::Document
include Mongoid::Timestamps
# include MongoMapper::Document # devise modules
devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable
## Attributes # attr_accessible :email, :password, :password_confirmation # TODO
# key :name
# key :locale
# timestamps!
# Include default devise modules. Others available are: ## attributes ##
# :http_authenticatable, :token_authenticatable, :lockable, :timeoutable and :activatable field :name
# devise :registerable, :authenticatable, :confirmable, :recoverable, field :locale, :default => 'en'
# :rememberable, :trackable, :validatable
## validations ##
validates_presence_of :name
## associations ##
def sites
Site.where({ :account_ids => self._id })
end
# Setup accessible (or protected) attributes for your model
# attr_accessible :email, :password, :password_confirmation
end end

View File

@ -6,6 +6,7 @@ class Site
field :name field :name
field :subdomain, :type => String field :subdomain, :type => String
field :domains, :type => Array, :default => [] field :domains, :type => Array, :default => []
field :account_ids, :type => Array, :default => []
## validations ## ## validations ##
validates_presence_of :name, :subdomain validates_presence_of :name, :subdomain
@ -26,6 +27,14 @@ class Site
## methods ## ## methods ##
def accounts
Account.criteria.in(:_id => self.account_ids)
end
def accounts=(models_or_ids)
self.account_ids = [*models_or_ids].collect { |object| object.respond_to?(:to_i) ? object : object.id }.uniq
end
def add_subdomain_to_domains def add_subdomain_to_domains
self.domains ||= [] self.domains ||= []
(self.domains << "#{self.subdomain}.#{Locomotive.config.default_domain}").uniq! (self.domains << "#{self.subdomain}.#{Locomotive.config.default_domain}").uniq!

View File

@ -0,0 +1,12 @@
<h2>Resend confirmation instructions</h2>
<%= form_for(resource_name, resource, :url => confirmation_path(resource_name)) do |f| %>
<%= f.error_messages %>
<p><%= f.label :email %></p>
<p><%= f.text_field :email %></p>
<p><%= f.submit "Resend confirmation instructions" %></p>
<% end %>
<%= render :partial => "devise/shared/links" %>

View File

@ -0,0 +1,5 @@
<p>Welcome <%= @resource.email %>!</p>
<p>You can confirm your account through the link below:</p>
<p><%= link_to 'Confirm my account', confirmation_url(@resource, :confirmation_token => @resource.confirmation_token) %></p>

View File

@ -0,0 +1,8 @@
<p>Hello <%= @resource.email %>!</p>
<p>Someone has requested a link to change your password, and you can do this through the link below.</p>
<p><%= link_to 'Change my password', edit_password_url(@resource, :reset_password_token => @resource.reset_password_token) %></p>
<p>If you didn't request this, please ignore this email.</p>
<p>Your password won't change until you access the link above and create a new one.</p>

View File

@ -0,0 +1,7 @@
<p>Hello <%= @resource.email %>!</p>
<p>Your account has been locked due to an excessive amount of unsuccessful sign in attempts.</p>
<p>Click the link below to unlock your account:</p>
<p><%= link_to 'Unlock my account', unlock_url(@resource, :unlock_token => @resource.unlock_token) %></p>

View File

@ -0,0 +1,16 @@
<h2>Change your password</h2>
<%= form_for(resource_name, resource, :url => password_path(resource_name), :html => { :method => :put }) do |f| %>
<%= f.error_messages %>
<%= f.hidden_field :reset_password_token %>
<p><%= f.label :password %></p>
<p><%= f.password_field :password %></p>
<p><%= f.label :password_confirmation %></p>
<p><%= f.password_field :password_confirmation %></p>
<p><%= f.submit "Change my password" %></p>
<% end %>
<%= render :partial => "devise/shared/links" %>

View File

@ -0,0 +1,12 @@
<h2>Forgot your password?</h2>
<%= form_for(resource_name, resource, :url => password_path(resource_name)) do |f| %>
<%= f.error_messages %>
<p><%= f.label :email %></p>
<p><%= f.text_field :email %></p>
<p><%= f.submit "Send me reset password instructions" %></p>
<% end %>
<%= render :partial => "devise/shared/links" %>

View File

@ -0,0 +1,25 @@
<h2>Edit <%= resource_name.to_s.humanize %></h2>
<%= form_for(resource_name, resource, :url => registration_path(resource_name), :html => { :method => :put }) do |f| %>
<%= f.error_messages %>
<p><%= f.label :email %></p>
<p><%= f.text_field :email %></p>
<p><%= f.label :password %> <i>(leave blank if you don't want to change it)</i></p>
<p><%= f.password_field :password %></p>
<p><%= f.label :password_confirmation %></p>
<p><%= f.password_field :password_confirmation %></p>
<p><%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i></p>
<p><%= f.password_field :current_password %></p>
<p><%= f.submit "Update" %></p>
<% end %>
<h3>Cancel my account</h3>
<p>Unhappy? <%= link_to "Cancel my account", registration_path(resource_name), :confirm => "Are you sure?", :method => :delete %>.</p>
<%= link_to "Back", :back %>

View File

@ -0,0 +1,17 @@
<h2>Sign up</h2>
<%= form_for(resource_name, resource, :url => registration_path(resource_name)) do |f| %>
<%= f.error_messages %>
<p><%= f.label :email %></p>
<p><%= f.text_field :email %></p>
<p><%= f.label :password %></p>
<p><%= f.password_field :password %></p>
<p><%= f.label :password_confirmation %></p>
<p><%= f.password_field :password_confirmation %></p>
<p><%= f.submit "Sign up" %></p>
<% end %>
<%= render :partial => "devise/shared/links" %>

View File

@ -0,0 +1,17 @@
<h2>Sign in</h2>
<%= form_for(resource_name, resource, :url => session_path(resource_name)) do |f| %>
<p><%= f.label :email %></p>
<p><%= f.text_field :email %></p>
<p><%= f.label :password %></p>
<p><%= f.password_field :password %></p>
<% if devise_mapping.rememberable? -%>
<p><%= f.check_box :remember_me %> <%= f.label :remember_me %></p>
<% end -%>
<p><%= f.submit "Sign in" %></p>
<% end %>
<%= render :partial => "devise/shared/links" %>

View File

@ -0,0 +1,19 @@
<%- if controller_name != 'sessions' %>
<%= link_to "Sign in", new_session_path(resource_name) %><br />
<% end -%>
<%- if devise_mapping.registerable? && controller_name != 'registrations' %>
<%= link_to "Sign up", new_registration_path(resource_name) %><br />
<% end -%>
<%- if devise_mapping.recoverable? && controller_name != 'passwords' %>
<%= link_to "Forgot your password?", new_password_path(resource_name) %><br />
<% end -%>
<%- if devise_mapping.confirmable? && controller_name != 'confirmations' %>
<%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name) %><br />
<% end -%>
<%- if devise_mapping.lockable? && controller_name != 'unlocks' %>
<%= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name) %><br />
<% end -%>

View File

@ -0,0 +1,12 @@
<h2>Resend unlock instructions</h2>
<%= form_for(resource_name, resource, :url => unlock_path(resource_name)) do |f| %>
<%= f.error_messages %>
<p><%= f.label :email %></p>
<p><%= f.text_field :email %></p>
<p><%= f.submit "Resend unlock instructions" %></p>
<% end %>
<%= render :partial => "devise/shared/links" %>

View File

@ -84,7 +84,6 @@ Devise.setup do |config|
# ==> General configuration # ==> General configuration
# Load and configure the ORM. Supports :active_record (default), :mongoid # Load and configure the ORM. Supports :active_record (default), :mongoid
# (requires mongo_ext installed) and :data_mapper (experimental). # (requires mongo_ext installed) and :data_mapper (experimental).
# require 'devise/orm/active_record'
require 'devise/orm/mongoid' require 'devise/orm/mongoid'
# Turn scoped views on. Before rendering "sessions/new", it will first check for # Turn scoped views on. Before rendering "sessions/new", it will first check for

View File

@ -3,3 +3,6 @@ require 'lib/locomotive.rb'
Locomotive.configure do |config| Locomotive.configure do |config|
config.default_domain = 'example.com' config.default_domain = 'example.com'
end end
# TODO: embed it in Locomotive
ActionMailer::Base.default_url_options[:host] = Locomotive.config.default_domain + (Rails.env.development? ? ':3000' : '')

View File

@ -2,6 +2,7 @@ Locomotive::Application.routes.draw do |map|
constraints(Locomotive::Routing::DefaultConstraint) do constraints(Locomotive::Routing::DefaultConstraint) do
root :to => 'home#show' root :to => 'home#show'
devise_for :accounts
end end
match '/' => 'pages#show' match '/' => 'pages#show'

View File

@ -8,3 +8,4 @@
Site.create! :name => 'Locomotive test website', :subdomain => 'test' Site.create! :name => 'Locomotive test website', :subdomain => 'test'
Account.create :name => 'Admin', :email => 'admin@locomotiveapp.org', :password => 'locomotive', :password_confirmation => 'locomotive'

View File

@ -5,13 +5,12 @@ Factory.define :site do |s|
s.created_at Time.now s.created_at Time.now
end end
## Accounts ## # Accounts ##
# Factory.define :account do |a| Factory.define :account do |a|
# a.name 'Bart Simpson' a.name 'Bart Simpson'
# a.email 'bart@fox.com' a.email 'bart@simpson.net'
# a.password 'easyone' a.password 'easyone'
# a.password_confirmation 'easyone' a.password_confirmation 'easyone'
# a.locale 'en' a.locale 'en'
# end end
## Site ##

View File

@ -0,0 +1,40 @@
require 'spec_helper'
describe Account do
it 'should have a valid factory' do
Factory.build(:account).should be_valid
end
## Validations ##
%w{name email password}.each do |attr|
it "should validate presence of #{attr}" do
account = Factory.build(:account, attr.to_sym => nil)
account.should_not be_valid
account.errors[attr.to_sym].should include("can't be blank")
end
end
it "should have a default locale" do
account = Factory.build(:account, :locale => nil)
account.should be_valid
account.locale.should == 'en'
end
it "should validate uniqueness of email" do
Factory(:account)
(account = Factory.build(:account)).should_not be_valid
account.errors[:email].should == ["is already taken"]
end
## Associations ##
it 'should own many sites' do
account = Factory(:account)
site_1 = Factory(:site, :accounts => account)
site_2 = Factory(:site, :subdomain => 'foo', :accounts => account)
account.sites.should == [site_1, site_2]
end
end

View File

@ -80,6 +80,16 @@ describe Site do
sites.should be_empty sites.should be_empty
end end
## Associations ##
it 'should have many accounts' do
account_1 = Factory(:account)
account_2 = Factory(:account, :name => 'homer', :email => 'homer@simpson.net')
site = Factory(:site, :accounts => [account_1, account_2, account_1])
site.account_ids.should == [account_1.id, account_2.id]
site.accounts.should == [account_1, account_2]
end
## Methods ## ## Methods ##
it 'should return domains without subdomain' do it 'should return domains without subdomain' do
@ -87,4 +97,5 @@ describe Site do
site.domains.should == %w{www.acme.net www.acme.com acme.example.com} site.domains.should == %w{www.acme.net www.acme.com acme.example.com}
site.domains_without_subdomain.should == %w{www.acme.net www.acme.com} site.domains_without_subdomain.should == %w{www.acme.net www.acme.com}
end end
end end