wristband 0.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +2 -1
- data/Gemfile.lock +3 -3
- data/README.md +121 -38
- data/Rakefile +1 -0
- data/VERSION +1 -1
- data/app/controllers/application_controller.rb +0 -6
- data/app/controllers/passwords_controller.rb +43 -0
- data/app/controllers/sessions_controller.rb +6 -7
- data/app/controllers/users_controller.rb +1 -26
- data/app/helpers/form_helper.rb +8 -0
- data/app/mailers/user_mailer.rb +4 -26
- data/app/models/user.rb +1 -2
- data/app/views/passwords/edit.html.haml +7 -0
- data/app/views/passwords/new.html.haml +15 -0
- data/app/views/sessions/new.html.haml +1 -5
- data/app/views/user_mailer/password_reset.html.haml +7 -0
- data/app/views/user_mailer/password_reset.text.haml +6 -0
- data/config/environment.rb +1 -0
- data/config/initializers/formatted_form_builder.rb +141 -0
- data/config/routes.rb +6 -9
- data/db/migrate/01_create_users_table.rb +5 -3
- data/db/schema.rb +7 -4
- data/lib/generators/wristband/wristband_generator.rb +26 -15
- data/lib/wristband/application_extensions.rb +1 -0
- data/lib/wristband/user_extensions.rb +7 -17
- data/lib/wristband.rb +1 -3
- data/test/dummy/user.rb +1 -1
- data/test/functional/passwords_controller_test.rb +62 -0
- data/test/functional/sessions_controller_test.rb +93 -0
- data/test/test_helper.rb +1 -5
- data/test/unit/has_authorities_test.rb +1 -8
- data/test/unit/session_user_test.rb +46 -4
- data/test/unit/user_mailer_test.rb +18 -0
- data/test/unit/user_test.rb +1 -72
- data/test/unit/wristband_test.rb +74 -0
- data/wristband.gemspec +27 -10
- metadata +62 -29
- data/app/views/user_mailer/email_verification.text.html.rhtml +0 -7
- data/app/views/user_mailer/email_verification.text.plain.rhtml +0 -9
- data/app/views/user_mailer/forgot_password.text.html.rhtml +0 -10
- data/app/views/user_mailer/forgot_password.text.plain.rhtml +0 -10
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -34,6 +34,7 @@ GEM
|
|
34
34
|
abstract (>= 1.0.0)
|
35
35
|
faker (0.9.4)
|
36
36
|
i18n (~> 0.4)
|
37
|
+
formatted_form (1.0.0)
|
37
38
|
git (1.2.5)
|
38
39
|
haml (3.0.25)
|
39
40
|
i18n (0.5.0)
|
@@ -68,8 +69,6 @@ GEM
|
|
68
69
|
thor (~> 0.14.4)
|
69
70
|
rake (0.8.7)
|
70
71
|
sqlite3 (1.3.3)
|
71
|
-
sqlite3-ruby (1.3.3)
|
72
|
-
sqlite3 (>= 1.3.3)
|
73
72
|
test_dummy (0.2.6)
|
74
73
|
thor (0.14.6)
|
75
74
|
treetop (1.4.9)
|
@@ -81,8 +80,9 @@ PLATFORMS
|
|
81
80
|
|
82
81
|
DEPENDENCIES
|
83
82
|
faker
|
83
|
+
formatted_form (= 1.0.0)
|
84
84
|
haml (= 3.0.25)
|
85
85
|
jeweler
|
86
86
|
rails (= 3.0.3)
|
87
|
-
sqlite3
|
87
|
+
sqlite3
|
88
88
|
test_dummy
|
data/README.md
CHANGED
@@ -11,6 +11,7 @@ It handles:
|
|
11
11
|
|
12
12
|
* Login and logout
|
13
13
|
* Password storage with encryption
|
14
|
+
* Password recovery
|
14
15
|
* Remember me functionality
|
15
16
|
* Authority definitions
|
16
17
|
|
@@ -25,30 +26,6 @@ It handles:
|
|
25
26
|
|
26
27
|
bundle install
|
27
28
|
|
28
|
-
### 3. (optional) Run the wristband generator:
|
29
|
-
|
30
|
-
rails g wristband
|
31
|
-
|
32
|
-
This will output something like:
|
33
|
-
|
34
|
-
create app/models/user.rb
|
35
|
-
create app/models/session_user.rb
|
36
|
-
create app/controllers/users_controller.rb
|
37
|
-
create app/controllers/sessions_controller.rb
|
38
|
-
create app/views/users/show.html.haml
|
39
|
-
create app/views/sessions/new.html.haml
|
40
|
-
create app/mailers/user_mailer.rb
|
41
|
-
create app/views/user_mailer/forgot_password.text.html.rhtml
|
42
|
-
create app/views/user_mailer/forgot_password.text.plain.rhtml
|
43
|
-
create app/views/user_mailer/email_verification.text.html.rhtml
|
44
|
-
create app/views/user_mailer/email_verification.text.plain.rhtml
|
45
|
-
create db/migrate/20110123214541_create_users_table.rb
|
46
|
-
|
47
|
-
### 4. (optional) Run migrations:
|
48
|
-
|
49
|
-
rake db:migrate
|
50
|
-
|
51
|
-
|
52
29
|
## Configuration
|
53
30
|
|
54
31
|
|
@@ -60,32 +37,32 @@ This will output something like:
|
|
60
37
|
|
61
38
|
### Options:
|
62
39
|
|
63
|
-
**:login_with** - Array of fields you want to authenticate the user with. Default: email
|
40
|
+
**:login_with** - Array of fields you want to authenticate the user with. *Default: `:email`*
|
64
41
|
|
65
42
|
wristband :login_with => [:username, :email]
|
66
43
|
|
67
44
|
|
68
|
-
**:before_authentication** - Array of functions run after the user authentication takes place. Default: []
|
45
|
+
**:before_authentication** - Array of functions run after the user authentication takes place. *Default: `[]`*
|
69
46
|
|
70
47
|
wristband :before_authentication => :do_something
|
71
48
|
|
72
49
|
|
73
|
-
**:after_authentication** - Array of functions run before the user authentication takes place. Default: []
|
50
|
+
**:after_authentication** - Array of functions run before the user authentication takes place. *Default: `[]`*
|
74
51
|
|
75
52
|
wristband :after_authentication => :do_something
|
76
53
|
|
77
|
-
|
78
|
-
**:has_authorities** - The different user authorities are defined in a separate class so as to reduce clutter in the User model itself. Default: false
|
79
|
-
|
80
|
-
wristband :has_authorities => true
|
81
|
-
|
82
|
-
**:roles** - Use this to define the different roles the user can assume. Make sure you have a role column on your users table. It will generate functions like `is_<role>?` for each one of the roles youdefine.
|
54
|
+
**:roles** - Use this to define the different roles the user can assume. Make sure you have a role column on your users table. It will generate functions like `is_<role>?` for each one of the roles you define.
|
83
55
|
|
84
56
|
wristband :roles => [:regular_user, :admin]
|
85
57
|
|
86
58
|
will generate `user.is_regular_user?` and `user.is_admin?`
|
87
59
|
|
88
60
|
|
61
|
+
**:has_authorities** - The different user authorities are defined in a separate class so as to reduce clutter in the User model itself. *Default: `false`*
|
62
|
+
|
63
|
+
wristband :has_authorities => true
|
64
|
+
|
65
|
+
Look for more details below.
|
89
66
|
|
90
67
|
## Notes
|
91
68
|
|
@@ -93,21 +70,127 @@ This will output something like:
|
|
93
70
|
2. **Authority Definitions** - Checkout the documentation on wristband/authority_check_rb
|
94
71
|
|
95
72
|
|
96
|
-
## Database configuration
|
97
73
|
|
98
|
-
|
74
|
+
## Personalization
|
75
|
+
|
76
|
+
Wristband comes with a generator that provides you with all the files you need to get started
|
77
|
+
|
78
|
+
rails g wristband
|
79
|
+
|
80
|
+
This will output something like:
|
81
|
+
|
82
|
+
== Models ==
|
83
|
+
create app/models/user.rb
|
84
|
+
create app/models/session_user.rb
|
85
|
+
== Controllers ==
|
86
|
+
create app/controllers/users_controller.rb
|
87
|
+
create app/controllers/sessions_controller.rb
|
88
|
+
create app/controllers/passwords_controller.rb
|
89
|
+
== Views ==
|
90
|
+
create app/views/users/show.html.haml
|
91
|
+
create app/views/sessions/new.html.haml
|
92
|
+
create app/views/passwords/new.html.haml
|
93
|
+
create app/views/passwords/edit.html.haml
|
94
|
+
== User Mailer ==
|
95
|
+
create app/mailers/user_mailer.rb
|
96
|
+
create app/views/user_mailer/password_reset.html.haml
|
97
|
+
create app/views/user_mailer/password_reset.text.haml
|
98
|
+
== Test helper and Dummies ==
|
99
|
+
create test/test_helper.rb
|
100
|
+
create test/dummy/user.rb
|
101
|
+
== Unit tests ==
|
102
|
+
create test/unit/user_test.rb
|
103
|
+
create test/unit/session_user_test.rb
|
104
|
+
create test/unit/user_mailer_test.rb
|
105
|
+
== Functional tests ==
|
106
|
+
create test/functional/sessions_controller_test.rb
|
107
|
+
create test/functional/passwords_controller_test.rb
|
108
|
+
== Migration ==
|
109
|
+
create db/migrate/20110123214541_create_users_table.rb
|
110
|
+
|
111
|
+
### Database configuration
|
112
|
+
|
99
113
|
The basic columns are defined as such:
|
100
114
|
|
101
115
|
create_table :users do |t|
|
102
116
|
t.string :email
|
103
|
-
t.string :
|
104
|
-
t.datetime :validated_at
|
105
|
-
t.string :password_crypt, :limit => 40
|
117
|
+
t.string :password_hash, :limit => 40
|
106
118
|
t.string :password_salt, :limit => 40
|
119
|
+
t.string :perishable_token
|
107
120
|
t.string :remember_token
|
108
121
|
t.string :role
|
109
122
|
t.timestamps
|
110
123
|
end
|
111
124
|
|
112
125
|
|
126
|
+
# AuthorityCheck
|
127
|
+
|
128
|
+
First you need to tell Wristband that you you want to define permissions for your user:
|
129
|
+
|
130
|
+
class User < ActiveRecord::Base
|
131
|
+
wristband :has_authorities => true
|
132
|
+
end
|
133
|
+
|
134
|
+
This will refer to the class `UserAuthorityCheck` for all authority tests, but the name of this module can be defined as required:
|
135
|
+
|
136
|
+
class User < ActiveRecord::Base
|
137
|
+
has_authorities => :permissions
|
138
|
+
end
|
139
|
+
|
140
|
+
That would reference the class `UserPermissions` instead for all tests.
|
141
|
+
|
142
|
+
A sample authority checking class is defined as:
|
143
|
+
|
144
|
+
class UserAuthorityCheck < AuthorityCheck
|
145
|
+
def wear_shoes?
|
146
|
+
unless (@user.name.match(/^a/i))
|
147
|
+
fail!("Only people with names that start with 'A' can wear shoes.")
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
**Note the syntax:** All authority checks are defined as ending with a trailing question mark character.
|
153
|
+
|
154
|
+
A check is considered to have passed if
|
155
|
+
|
156
|
+
* a call to `allow!` has been made, or
|
157
|
+
* no calls to `fail!` have been made.
|
158
|
+
|
159
|
+
Once defined, the user authorities are checked via a call to a `User` instance:
|
160
|
+
|
161
|
+
user.has_authority_to?(:wear_shoes)
|
162
|
+
|
163
|
+
While the `has_authority_to?` method returns only true or false, a call to `has_objections_to?` will return nil on success or any error messages if there is a failure.
|
164
|
+
|
165
|
+
|
166
|
+
## Passing parameters to the authority methods
|
167
|
+
|
168
|
+
Any call to these tests may include options in the form of a Hash:
|
169
|
+
|
170
|
+
user.has_authority_to?(:send_message, :text => "Foo bar")
|
171
|
+
|
172
|
+
These options can be acted upon within the authority check:
|
173
|
+
|
174
|
+
def send_message?
|
175
|
+
if (options[:text].match(/foo/i))
|
176
|
+
fail!("Messages may not contain forbidden words.")
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
## Before chains
|
181
|
+
|
182
|
+
In addition to defining straight tests, a chain can be defined to run before
|
183
|
+
any of the tests themselves. This allows certain calls to be over-ruled. For
|
184
|
+
example:
|
185
|
+
|
186
|
+
before_check :allow_if_admin!
|
187
|
+
|
188
|
+
def allow_if_admin!
|
189
|
+
if (@user.is_admin?)
|
190
|
+
allow!
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
In this case, the 'allow_if_admin!` method will be called before any checks are performed. If the `allow!` method is executed, all subsequent tests are halted and the check is considered to have passed.
|
195
|
+
|
113
196
|
Have fun!!
|
data/Rakefile
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
1.0.2
|
@@ -0,0 +1,43 @@
|
|
1
|
+
class PasswordsController < ApplicationController
|
2
|
+
before_filter :redirect_if_logged_in, :only => [ :new, :create ]
|
3
|
+
before_filter :load_user_by_perishable_token, :only => [:edit, :update]
|
4
|
+
|
5
|
+
def new
|
6
|
+
# ...
|
7
|
+
end
|
8
|
+
|
9
|
+
def create
|
10
|
+
user = User.find_by_email!(params[:email])
|
11
|
+
user.reset_perishable_token!
|
12
|
+
UserMailer.password_reset(user).deliver
|
13
|
+
redirect_to login_path, :notice => 'Email to reset password successfully sent.'
|
14
|
+
rescue ActiveRecord::RecordNotFound
|
15
|
+
flash.now[:alert] = 'Your email was not found. Did you mistype?'
|
16
|
+
render :action => :new
|
17
|
+
end
|
18
|
+
|
19
|
+
def edit
|
20
|
+
# ...
|
21
|
+
end
|
22
|
+
|
23
|
+
def update
|
24
|
+
@user.update_attributes!(params[:user].merge(:perishable_token => nil))
|
25
|
+
login_as_user(@user)
|
26
|
+
redirect_to user_path(@user), :notice => 'Your password was successfully updated!'
|
27
|
+
rescue ActiveRecord::RecordInvalid
|
28
|
+
flash[:notice] = 'An error occurred. Please try again.'
|
29
|
+
redirect_to login_path
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
protected
|
34
|
+
def load_user_by_perishable_token
|
35
|
+
@user = User.find_by_perishable_token!(params[:id])
|
36
|
+
rescue ActiveRecord::RecordNotFound
|
37
|
+
redirect_to login_path
|
38
|
+
end
|
39
|
+
|
40
|
+
def redirect_if_logged_in
|
41
|
+
redirect_to user_path(current_user) if logged_in?
|
42
|
+
end
|
43
|
+
end
|
@@ -1,31 +1,30 @@
|
|
1
1
|
class SessionsController < ApplicationController
|
2
2
|
before_filter :login_required, :only => :destroy
|
3
|
-
before_filter :redirect_if_logged_in, :only => [ :new, :create
|
3
|
+
before_filter :redirect_if_logged_in, :only => [ :new, :create ]
|
4
4
|
before_filter :build_user_session, :only => [ :new, :create ]
|
5
5
|
|
6
6
|
def create
|
7
7
|
if @session_user.save
|
8
8
|
login(@session_user)
|
9
|
-
|
10
|
-
redirect_to user_path(current_user)
|
9
|
+
redirect_to(user_path(current_user), :notice => "Welcome, you are now logged in.")
|
11
10
|
else
|
12
|
-
flash[:
|
11
|
+
flash[:alert] = 'Login failed. Did you mistype?'
|
13
12
|
render :action => :new
|
14
13
|
end
|
15
14
|
end
|
16
15
|
|
17
16
|
def destroy
|
18
17
|
logout
|
19
|
-
redirect_to
|
18
|
+
redirect_to login_path
|
20
19
|
end
|
21
20
|
|
22
|
-
|
21
|
+
protected
|
23
22
|
def build_user_session
|
24
23
|
@session_user = SessionUser.new(params[:session_user])
|
25
24
|
end
|
26
25
|
|
27
26
|
def redirect_if_logged_in
|
28
|
-
redirect_to
|
27
|
+
redirect_to user_path(current_user) if logged_in?
|
29
28
|
end
|
30
29
|
|
31
30
|
def login_required
|
@@ -1,32 +1,7 @@
|
|
1
1
|
class UsersController < ApplicationController
|
2
2
|
before_filter :login_required
|
3
3
|
|
4
|
-
|
5
|
-
@user = User.verify_email!(params[:email_validation_key])
|
6
|
-
flash[:notice] = 'Your email address has been verified. You may now login to your account.'
|
7
|
-
redirect_to login_path
|
8
|
-
rescue UserVerificationError => error
|
9
|
-
flash[:error] = error.message
|
10
|
-
redirect_to login_path
|
11
|
-
end
|
12
|
-
|
13
|
-
def forgot_password
|
14
|
-
if request.post?
|
15
|
-
if @user = User.find_by_email(params[:user][:email])
|
16
|
-
@user.password = Wristband::Support.random_string(6)
|
17
|
-
@user.save!
|
18
|
-
UserNotifier::deliver_forgot_password(@user)
|
19
|
-
flash[:notice] = 'A new password has been generated and emailed to the address you entered.'
|
20
|
-
redirect_to login_path and return
|
21
|
-
else
|
22
|
-
@user = User.new
|
23
|
-
@user.errors.add("email", "Cannot find that email address, did you mistype?")
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
|
29
|
-
private
|
4
|
+
protected
|
30
5
|
def login_required
|
31
6
|
redirect_to login_path unless logged_in?
|
32
7
|
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
module FormHelper
|
2
|
+
def formatted_form_for(record_or_name_or_array, *args, &proc)
|
3
|
+
options = args.extract_options!
|
4
|
+
options.merge!(:builder => FormattedFormBuilder)
|
5
|
+
(options[:html] ||= { }).merge!(:class => "#{options[:html][:class]} formatted")
|
6
|
+
form_for(record_or_name_or_array, *(args << options), &proc)
|
7
|
+
end
|
8
|
+
end
|
data/app/mailers/user_mailer.rb
CHANGED
@@ -1,33 +1,11 @@
|
|
1
1
|
class UserMailer < ActionMailer::Base
|
2
2
|
default :from => "from@example.com"
|
3
3
|
|
4
|
-
default_url_options[:host] =
|
5
|
-
|
6
|
-
def email_verification(user)
|
7
|
-
setup_email(user)
|
8
|
-
@subject += "Your account has been created. Please verify your email address"
|
9
|
-
end
|
4
|
+
default_url_options[:host] = 'open-porch.local'
|
10
5
|
|
11
|
-
def
|
12
|
-
|
13
|
-
|
6
|
+
def password_reset(user)
|
7
|
+
@user = user
|
8
|
+
mail(:to => user.email, :subject => "You have requested a new password")
|
14
9
|
end
|
15
10
|
|
16
|
-
|
17
|
-
protected
|
18
|
-
# Change YourApp to whatever you application is called
|
19
|
-
def setup_email(user)
|
20
|
-
@recipients = user.email
|
21
|
-
@body[:user] = user
|
22
|
-
@from = FROM_EMAIL
|
23
|
-
@subject = case ENV['RAILS_ENV']
|
24
|
-
when 'development'
|
25
|
-
"[YourApp Development] "
|
26
|
-
when 'staging'
|
27
|
-
"[YourApp Staging] "
|
28
|
-
else "[YourApp] "
|
29
|
-
end
|
30
|
-
@sent_on = Time.now
|
31
|
-
headers "Reply-to" => FROM_EMAIL
|
32
|
-
end
|
33
11
|
end
|
data/app/models/user.rb
CHANGED
@@ -2,7 +2,7 @@ class User < ActiveRecord::Base
|
|
2
2
|
|
3
3
|
# == Constants ============================================================
|
4
4
|
|
5
|
-
ROLES =
|
5
|
+
ROLES = %W{admin regular_user}
|
6
6
|
|
7
7
|
# == Extensions ===========================================================
|
8
8
|
|
@@ -48,5 +48,4 @@ class User < ActiveRecord::Base
|
|
48
48
|
def password_required?
|
49
49
|
self.new_record?
|
50
50
|
end
|
51
|
-
|
52
51
|
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
%h1 Enter a new Password
|
2
|
+
|
3
|
+
= formatted_form_for @user, :url => { :action => :update, :id => params[:id] } do |form|
|
4
|
+
= form.error_messages
|
5
|
+
= form.password_field :password, :autocomplete => :off
|
6
|
+
= form.password_field :password_confirmation, :label => 'Password Confim'
|
7
|
+
= form.submit 'Update'
|
@@ -0,0 +1,15 @@
|
|
1
|
+
%h1 Reset your password
|
2
|
+
|
3
|
+
= form_tag passwords_path, :class => 'formatted' do
|
4
|
+
.form_element.text_field_element
|
5
|
+
.label Email
|
6
|
+
.value= text_field_tag :email
|
7
|
+
|
8
|
+
.form_element.submit_element
|
9
|
+
= submit_tag 'Send Reset Password Email'
|
10
|
+
|
11
|
+
|
12
|
+
|
13
|
+
%p
|
14
|
+
Already have an account?
|
15
|
+
= link_to 'Login', login_path
|
data/config/environment.rb
CHANGED
@@ -0,0 +1,141 @@
|
|
1
|
+
class FormattedFormBuilder < ActionView::Helpers::FormBuilder
|
2
|
+
|
3
|
+
%w[ date_select text_field password_field text_area file_field datetime_select ].each do |selector|
|
4
|
+
src = <<-end_src
|
5
|
+
def #{selector}(method, options = {})
|
6
|
+
if (options[:simple] == true)
|
7
|
+
super(method, options)
|
8
|
+
else
|
9
|
+
options.merge!(:size=> '') if #{%w{text_field password_field}.include?(selector)}
|
10
|
+
standard_field('#{selector}', method, options) { super(method, options) }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end_src
|
14
|
+
class_eval src, __FILE__, __LINE__
|
15
|
+
end
|
16
|
+
|
17
|
+
def standard_field(type, method, options={}, &block)
|
18
|
+
description = options.delete(:desc)
|
19
|
+
content = options.delete(:content)
|
20
|
+
prev_content = options.delete(:prev_content)
|
21
|
+
label = label_for(method, options)
|
22
|
+
required = options.delete(:required)
|
23
|
+
check_box_details = options.delete(:check_box_details)
|
24
|
+
text_snippet = options.delete(:text_snippet)
|
25
|
+
%{
|
26
|
+
<div class='form_element #{type}_element'>
|
27
|
+
#{"<div class='text_snippet'>"+text_snippet+"</div>" if text_snippet}
|
28
|
+
<div class='label'>
|
29
|
+
#{description(description) || ' ' if type == 'check_box' }
|
30
|
+
#{label if type != 'check_box' }
|
31
|
+
#{@template.content_tag(:span, '*', :class => 'required_ind') if required }
|
32
|
+
</div>
|
33
|
+
<div class='value'>
|
34
|
+
#{prev_content}#{yield}#{content}
|
35
|
+
#{error_messages_for(method)}
|
36
|
+
#{description(description) if type != 'check_box'}
|
37
|
+
#{description(check_box_details) if type == 'check_box'}
|
38
|
+
</div>
|
39
|
+
</div>
|
40
|
+
}.html_safe
|
41
|
+
end
|
42
|
+
|
43
|
+
# generic container for all things form
|
44
|
+
def element(label = ' ', value = '', type = 'text_field', &block)
|
45
|
+
value += @template.capture(&block) if block_given?
|
46
|
+
%{
|
47
|
+
<div class='form_element #{type}_element'>
|
48
|
+
<div class='label'>
|
49
|
+
#{label}
|
50
|
+
</div>
|
51
|
+
<div class='value'>
|
52
|
+
#{value}
|
53
|
+
</div>
|
54
|
+
</div>
|
55
|
+
}.html_safe
|
56
|
+
end
|
57
|
+
|
58
|
+
def check_box(method, options = {}, checked_value = "1", unchecked_value = "0")
|
59
|
+
options[:content] = label_for(method, options)
|
60
|
+
options[:label] = ''
|
61
|
+
standard_field('check_box', method, options) { super(method, options, checked_value, unchecked_value) }
|
62
|
+
end
|
63
|
+
|
64
|
+
def radio_button(method, tag_value, options = {})
|
65
|
+
if options && options[:choices]
|
66
|
+
radios = options.delete(:choices).collect{|choice| %{<div class="radio_button">}+super(method, choice[0], options) + %{<label for="#{object_name.to_s.gsub(']', '').gsub('[', '_')}_#{method}_#{choice[0]}">#{choice[1]}</label></div>}}.join.html_safe
|
67
|
+
standard_field('radio_button', method, options) { radios }
|
68
|
+
elsif options && options[:value_name]
|
69
|
+
standard_field('radio_button', method, options) { super(method, tag_value) + %{<label for="#{object_name}_#{method}_#{tag_value}">#{options[:value_name]}</label><div class="clearfloat"></div>}.html_safe}
|
70
|
+
else
|
71
|
+
standard_field('radio_button', method, options) { super(method, tag_value, options = {}) }
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def select(method, choices, options = {}, html_options = {})
|
76
|
+
standard_field('select', method, options) { super(method, choices, options, html_options) }
|
77
|
+
end
|
78
|
+
|
79
|
+
def hidden_field(method, options = {}, html_options = {})
|
80
|
+
super(method, options)
|
81
|
+
end
|
82
|
+
|
83
|
+
def submit(value, options={}, &block)
|
84
|
+
cancel_link = @template.capture(&block) if block_given?
|
85
|
+
cancel_link ||= options[:cancel_url] ? ' or ' + options.delete(:cancel_url) : ''
|
86
|
+
if options[:show_ajax_loader]
|
87
|
+
options[:onclick] = "$(this).parent().next().css('display', 'block');$(this).parent().hide();"
|
88
|
+
end
|
89
|
+
if options[:image_button] == true
|
90
|
+
submit_id = Time.now.usec
|
91
|
+
out = @template.content_tag(:div,
|
92
|
+
%{
|
93
|
+
#{super(value, options.merge(:style=>'visibility:hidden;position: absolute', :id => submit_id)).html_safe}
|
94
|
+
<a class="red_button" href="" onclick="$('##{submit_id}').closest('form').submit();return false"><span>#{value}</span></a>
|
95
|
+
#{cancel_link.html_safe}
|
96
|
+
}.html_safe, :class => 'form_element submit_element').html_safe
|
97
|
+
|
98
|
+
else
|
99
|
+
out = @template.content_tag(:div, super(value, options) + cancel_link.html_safe, :class => 'form_element submit_element').html_safe
|
100
|
+
end
|
101
|
+
|
102
|
+
if options[:show_ajax_loader]
|
103
|
+
out << %{
|
104
|
+
<div class="form_element submit_element" style="display:none">
|
105
|
+
<div class="submit_ajax_loader">#{options[:show_ajax_loader]}</div>
|
106
|
+
</div>
|
107
|
+
}.html_safe
|
108
|
+
end
|
109
|
+
out.html_safe
|
110
|
+
end
|
111
|
+
|
112
|
+
def label_for(method, options)
|
113
|
+
label = options.delete(:label) || method.to_s.titleize.capitalize
|
114
|
+
"<label for=\"#{object_name}_#{method}\">#{label}</label>"
|
115
|
+
end
|
116
|
+
|
117
|
+
def description(description)
|
118
|
+
"<div class='description'>#{description}</div>" unless description.nil?
|
119
|
+
end
|
120
|
+
|
121
|
+
def error_messages
|
122
|
+
if object && !object.errors.empty?
|
123
|
+
message = object.errors[:base].present? ? object.errors[:base]: 'There were some problems submitting this form. Please correct all the highlighted fields and try again'
|
124
|
+
@template.content_tag(:div, message, :class => 'form_error')
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def error_messages_for(method)
|
129
|
+
if (object and object.respond_to?(:errors) and errors = object.errors[method])
|
130
|
+
"<div class='errors'>#{errors.is_a?(Array) ? errors.first : errors}</div>"
|
131
|
+
else
|
132
|
+
''
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def formatted_fields_for(record_or_name_or_array, *args, &block)
|
137
|
+
options = args.extract_options!
|
138
|
+
options.merge!(:builder => FormattedFormBuilder)
|
139
|
+
fields_for(record_or_name_or_array, *(args << options), &block)
|
140
|
+
end
|
141
|
+
end
|
data/config/routes.rb
CHANGED
@@ -1,11 +1,8 @@
|
|
1
|
-
Rails
|
2
|
-
|
3
|
-
|
4
|
-
get '/
|
5
|
-
get '/logout', :to => 'sessions#destroy'
|
6
|
-
match '/forgot_password', :to => 'sessions#forgot_password'
|
7
|
-
|
8
|
-
resources :users
|
9
|
-
match '/register', :to => 'users#new'
|
1
|
+
Rails.application.routes.draw do
|
2
|
+
post '/login' => 'sessions#create'
|
3
|
+
get '/login' => 'sessions#new'
|
4
|
+
get '/logout' => 'sessions#destroy'
|
10
5
|
|
6
|
+
resources :users
|
7
|
+
resources :passwords, :only => [:new, :create, :edit, :update]
|
11
8
|
end
|