open_conference_ware 1.0.0.pre2 → 1.0.0.pre3
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/.travis.yml +3 -0
- data/README.md +6 -4
- data/app/assets/javascripts/open_conference_ware/{persona.js → persona.js.erb} +1 -1
- data/app/assets/stylesheets/open_conference_ware/custom.css.scss +14 -18
- data/app/controllers/open_conference_ware/application_controller.rb +2 -2
- data/app/controllers/open_conference_ware/authentications_controller.rb +8 -0
- data/app/controllers/open_conference_ware/manage/events_controller.rb +2 -2
- data/app/controllers/open_conference_ware/proposals_controller.rb +1 -1
- data/app/helpers/open_conference_ware/snippets_helper.rb +1 -1
- data/app/helpers/open_conference_ware/user_favorites_helper.rb +8 -4
- data/app/mixins/open_conference_ware/settings_checkers_mixin.rb +1 -0
- data/app/models/open_conference_ware/event.rb +1 -8
- data/app/models/open_conference_ware/proposal.rb +54 -61
- data/app/models/open_conference_ware/snippet.rb +1 -6
- data/app/observers/open_conference_ware/cache_watcher.rb +3 -3
- data/app/views/layouts/open_conference_ware/_header.html.erb +3 -1
- data/app/views/open_conference_ware/422.html.erb +1 -1
- data/app/views/open_conference_ware/500.html.erb +1 -1
- data/app/views/open_conference_ware/proposals/_form.html.erb +5 -5
- data/app/views/open_conference_ware/proposals/_list.html.erb +4 -4
- data/app/views/open_conference_ware/proposals/_list_concise.html.erb +3 -3
- data/app/views/open_conference_ware/proposals/_sub_list.html.erb +2 -2
- data/app/views/open_conference_ware/proposals/_transition_control.html.erb +2 -2
- data/app/views/open_conference_ware/proposals/show.html.erb +33 -54
- data/db/migrate/20131203235216_create_open_conference_ware_comments.rb +1 -1
- data/db/migrate/20131203235418_create_open_conference_ware_events.rb +1 -2
- data/db/migrate/20131203235524_create_open_conference_ware_proposals.rb +5 -5
- data/db/migrate/20131203235723_create_open_conference_ware_rooms.rb +1 -1
- data/db/migrate/20131203235831_create_open_conference_ware_schedule_items.rb +2 -2
- data/db/migrate/20131203235934_create_open_conference_ware_session_types.rb +1 -1
- data/db/migrate/20131204000008_create_open_conference_ware_snippets.rb +1 -1
- data/db/migrate/20131204000048_create_open_conference_ware_taggings.rb +2 -2
- data/db/migrate/20131204000147_create_open_conference_ware_tracks.rb +1 -1
- data/db/migrate/20131204000355_create_proposals_users_join_table.rb +3 -0
- data/lib/generators/open_conference_ware/install/install_generator.rb +10 -0
- data/lib/generators/open_conference_ware/install/templates/config_initializer.rb +24 -2
- data/lib/generators/open_conference_ware/install/templates/secret_token.rb.erb +13 -0
- data/lib/generators/open_conference_ware/install/templates/secrets.yml.erb +18 -0
- data/lib/open_conference_ware.rb +10 -4
- data/lib/open_conference_ware/dependencies.rb +0 -1
- data/lib/open_conference_ware/version.rb +1 -1
- data/lib/tasks/open_conference_ware_tasks.rake +3 -2
- data/open_conference_ware.gemspec +0 -1
- data/spec/controllers/open_conference_ware/proposals_controller_spec.rb +5 -5
- data/spec/dummy/config/initializers/01_open_conference_ware.rb +24 -2
- data/spec/dummy/config/initializers/02_omniauth.rb +1 -1
- data/spec/dummy/config/initializers/secret_token.rb +2 -1
- data/spec/dummy/config/secrets.yml +18 -0
- data/spec/spec_helper_customizations.rb +2 -1
- data/spec/views/open_conference_ware/proposals/_transition_control.html.erb_spec.rb +2 -1
- data/spec/views/open_conference_ware/rooms/show.html.erb_spec.rb +1 -0
- data/spec/views/open_conference_ware/session_types/show.html.erb_spec.rb +1 -0
- data/spec/views/open_conference_ware/tracks/show.html.erb_spec.rb +1 -0
- data/util/transfer_schedule_items.rb +1 -1
- data/util/user_favorites_contention_report.rb +1 -1
- metadata +7 -22
- metadata.gz.sig +0 -0
- data/app/mixins/open_conference_ware/cache_lookups_mixin.rb +0 -128
- data/spec/integration/open_conference_ware/cache_lookups_mixin_spec.rb +0 -122
data.tar.gz.sig
CHANGED
Binary file
|
data/.travis.yml
CHANGED
@@ -11,7 +11,10 @@ env:
|
|
11
11
|
- DB=postgresql
|
12
12
|
- DB=sqlite
|
13
13
|
before_script:
|
14
|
+
- sqlite3 --version
|
15
|
+
- mysql --version
|
14
16
|
- mysql -e 'create database ocw_test;'
|
17
|
+
- psql --version
|
15
18
|
- psql -c 'create database ocw_test;' -U postgres
|
16
19
|
- ruby ci/copy_database_config.rb
|
17
20
|
- bundle exec rake db:migrate
|
data/README.md
CHANGED
@@ -34,11 +34,11 @@ OpenConferenceWare requires Ruby 1.9.3 and a host application built on Rails 4.0
|
|
34
34
|
|
35
35
|
3. Add 'open_conference_ware' to the newly-created app's Gemfile
|
36
36
|
|
37
|
-
gem "open_conference_ware"
|
37
|
+
gem "open_conference_ware", "~> 1.0.0.pre"
|
38
38
|
|
39
39
|
4. Run `bundle install`
|
40
40
|
|
41
|
-
5. Optionally, configure your app's [database settings](http://guides.rubyonrails.org/configuring.html#configuring-a-database). It's fine to run with the default sqlite configuration, but if you prefer another database, set it up now. OCW is tested with SQLite3, MySQL, and PostgreSQL.
|
41
|
+
5. Optionally, configure your app's [database settings](http://guides.rubyonrails.org/configuring.html#configuring-a-database). It's fine to run with the default sqlite configuration, but if you prefer another database, set it up now. OCW is tested with SQLite3, MySQL 5.5, and PostgreSQL 9.3.
|
42
42
|
|
43
43
|
6. Install OpenConferenceWare's configuration files and seed data:
|
44
44
|
|
@@ -48,9 +48,11 @@ OpenConferenceWare requires Ruby 1.9.3 and a host application built on Rails 4.0
|
|
48
48
|
|
49
49
|
$ bin/rails generate open_conference_ware:install /ocw
|
50
50
|
|
51
|
-
7. Edit `config/initializers/01_open_conference_ware.rb` to configure OCW's settings. You'll find comments
|
51
|
+
7. Edit `config/initializers/01_open_conference_ware.rb` and `config/secrets.yml` to configure OCW's settings. You'll find comments in these files explaining the available options.
|
52
52
|
|
53
|
-
8.
|
53
|
+
8. All of these newly-generated files, _except config/secrets.yml_, should be added to your version control system. If you're using git, you may want to add `config/secrets.yml` to your `.gitignore`, to ensure it doesn't get shared accidentally.
|
54
|
+
|
55
|
+
9. At this point, you should be able to fire up a server and see OpenConferenceWare at [http://localhost:3000](http://localhost:3000)
|
54
56
|
|
55
57
|
$ bin/rails server
|
56
58
|
|
@@ -4,7 +4,7 @@ function personaLogin() {
|
|
4
4
|
$('#persona_form input[name=assertion]').val(assertion);
|
5
5
|
$('#persona_form').submit();
|
6
6
|
} else {
|
7
|
-
window.location = "
|
7
|
+
window.location = "<%= OpenConferenceWare::Engine.routes.url_helpers.auth_failure_path %>"
|
8
8
|
}
|
9
9
|
});
|
10
10
|
}
|
@@ -13,10 +13,6 @@ div.skip-link a {
|
|
13
13
|
position: relative;
|
14
14
|
}
|
15
15
|
|
16
|
-
body {
|
17
|
-
padding-top: 1em;
|
18
|
-
}
|
19
|
-
|
20
16
|
/* @group Common Helper Classes */
|
21
17
|
|
22
18
|
div.admin-only {
|
@@ -83,7 +79,7 @@ span.admin-only {
|
|
83
79
|
top: 50%;
|
84
80
|
left: 50%;
|
85
81
|
color: black;
|
86
|
-
background: image-url('spinner-big.gif') no-repeat center #F7F1A3;
|
82
|
+
background: image-url('open_conference_ware/spinner-big.gif') no-repeat center #F7F1A3;
|
87
83
|
text-align: center;
|
88
84
|
padding: 10px;
|
89
85
|
font: normal 16px Tahoma, Geneva, sans-serif;
|
@@ -115,40 +111,40 @@ span.admin-only {
|
|
115
111
|
}
|
116
112
|
|
117
113
|
.addable {
|
118
|
-
background-image: image-url('plus.png');
|
114
|
+
background-image: image-url('open_conference_ware/plus.png');
|
119
115
|
}
|
120
116
|
|
121
117
|
.showable {
|
122
|
-
background-image: image-url('document.png');
|
118
|
+
background-image: image-url('open_conference_ware/document.png');
|
123
119
|
}
|
124
120
|
|
125
121
|
.editable,
|
126
122
|
.snippet_edit_link {
|
127
|
-
background-image: image-url('edit.png');
|
123
|
+
background-image: image-url('open_conference_ware/edit.png');
|
128
124
|
}
|
129
125
|
|
130
126
|
.cancelable {
|
131
|
-
background-image: image-url('arrow-out.png');
|
127
|
+
background-image: image-url('open_conference_ware/arrow-out.png');
|
132
128
|
}
|
133
129
|
|
134
130
|
.deletable {
|
135
|
-
background-image: image-url('delete.png');
|
131
|
+
background-image: image-url('open_conference_ware/delete.png');
|
136
132
|
}
|
137
133
|
|
138
134
|
.confirmable {
|
139
|
-
background-image: image-url('accept.png');
|
135
|
+
background-image: image-url('open_conference_ware/accept.png');
|
140
136
|
}
|
141
137
|
|
142
138
|
.feedable {
|
143
|
-
background-image: image-url('feed.png');
|
139
|
+
background-image: image-url('open_conference_ware/feed.png');
|
144
140
|
}
|
145
141
|
|
146
142
|
.spinning {
|
147
|
-
background-image: image-url('spinner.gif');
|
143
|
+
background-image: image-url('open_conference_ware/spinner.gif');
|
148
144
|
}
|
149
145
|
|
150
146
|
.to_top {
|
151
|
-
background-image: image-url('arrow-up.png');
|
147
|
+
background-image: image-url('open_conference_ware/arrow-up.png');
|
152
148
|
}
|
153
149
|
|
154
150
|
.popup {
|
@@ -156,7 +152,7 @@ span.admin-only {
|
|
156
152
|
padding-left: 20px;
|
157
153
|
background-position: left center;
|
158
154
|
background-repeat: no-repeat;
|
159
|
-
background-image: image-url('new_window.gif');
|
155
|
+
background-image: image-url('open_conference_ware/new_window.gif');
|
160
156
|
}
|
161
157
|
|
162
158
|
/* @end */
|
@@ -904,7 +900,7 @@ ul.calendar_items {
|
|
904
900
|
}
|
905
901
|
|
906
902
|
.favorite {
|
907
|
-
background-image: image-url('favorite.png');
|
903
|
+
background-image: image-url('open_conference_ware/favorite.png');
|
908
904
|
background-position: left -36px;
|
909
905
|
background-repeat: no-repeat;
|
910
906
|
width: 18px;
|
@@ -956,7 +952,7 @@ body.proposals.show #content h2.page_title {
|
|
956
952
|
}
|
957
953
|
|
958
954
|
a.to_favorites {
|
959
|
-
background: image-url('star.png') no-repeat left center;
|
955
|
+
background: image-url('open_conference_ware/star.png') no-repeat left center;
|
960
956
|
padding: 0 0 0 22px;
|
961
957
|
}
|
962
958
|
/* @end */
|
@@ -966,7 +962,7 @@ body.users.show h2.page_title {
|
|
966
962
|
}
|
967
963
|
|
968
964
|
.locked {
|
969
|
-
background: image-url('lock.png') no-repeat 0 2px;
|
965
|
+
background: image-url('open_conference_ware/lock.png') no-repeat 0 2px;
|
970
966
|
padding-left: 23px;
|
971
967
|
margin: 1em 0;
|
972
968
|
}
|
@@ -242,7 +242,7 @@ module OpenConferenceWare
|
|
242
242
|
|
243
243
|
# Assign an @events variable for use by the layout when displaying available events.
|
244
244
|
def assign_events
|
245
|
-
@events = Event.
|
245
|
+
@events = Event.all
|
246
246
|
end
|
247
247
|
|
248
248
|
# Return the event and a status which describes how the event was assigned. The status can be one of the following:
|
@@ -257,7 +257,7 @@ module OpenConferenceWare
|
|
257
257
|
# Try finding event using params:
|
258
258
|
event_id_key = controller_name == "events" ? :id : :event_id
|
259
259
|
if key = params[event_id_key]
|
260
|
-
if event = Event.
|
260
|
+
if event = Event.find(key)
|
261
261
|
return [event, :assigned_to_param]
|
262
262
|
else
|
263
263
|
logger.info "error, couldn't find event from key: #{key}"
|
@@ -2,6 +2,9 @@ module OpenConferenceWare
|
|
2
2
|
class AuthenticationsController < ApplicationController
|
3
3
|
before_filter :require_auth_hash, only: [:create]
|
4
4
|
|
5
|
+
# We need to accept a raw POST from an OmniAuth provider with no authenticity token.
|
6
|
+
skip_before_filter :verify_authenticity_token, :only => :create
|
7
|
+
|
5
8
|
def sign_in
|
6
9
|
page_title "Sign In"
|
7
10
|
end
|
@@ -29,6 +32,11 @@ module OpenConferenceWare
|
|
29
32
|
redirect_back_or_default
|
30
33
|
end
|
31
34
|
|
35
|
+
def failure
|
36
|
+
flash[:error] = params[:message]
|
37
|
+
redirect sign_in_path
|
38
|
+
end
|
39
|
+
|
32
40
|
protected
|
33
41
|
|
34
42
|
def auth_hash
|
@@ -11,7 +11,7 @@ module OpenConferenceWare
|
|
11
11
|
# GET /events
|
12
12
|
# GET /events.xml
|
13
13
|
def index
|
14
|
-
@events = Event.
|
14
|
+
@events = Event.all
|
15
15
|
|
16
16
|
respond_to do |format|
|
17
17
|
format.html # index.html.erb
|
@@ -108,7 +108,7 @@ module OpenConferenceWare
|
|
108
108
|
already_emailed = []
|
109
109
|
proposals = params[:proposal_ids].split(',')
|
110
110
|
proposals.each do |proposal_id|
|
111
|
-
proposal = Proposal.
|
111
|
+
proposal = Proposal.find(proposal_id) rescue nil
|
112
112
|
next unless proposal
|
113
113
|
case params[:proposal_status]
|
114
114
|
when 'accepted'
|
@@ -393,7 +393,7 @@ module OpenConferenceWare
|
|
393
393
|
# * :invalid_proposal
|
394
394
|
# * :invalid_event
|
395
395
|
def get_proposal_and_assignment_status
|
396
|
-
if proposal = Proposal.
|
396
|
+
if proposal = Proposal.find(params[:id].to_i) rescue nil
|
397
397
|
if proposal.event
|
398
398
|
return [proposal, :assigned_via_param]
|
399
399
|
else
|
@@ -4,7 +4,7 @@ module OpenConferenceWare
|
|
4
4
|
# Return the Snippet record matching the +slug+, else raise a
|
5
5
|
# ActiveRecord::RecordNotFound.
|
6
6
|
def snippet_record_for(slug)
|
7
|
-
if record = Snippet.
|
7
|
+
if record = Snippet.find_by_slug(slug.to_s)
|
8
8
|
return record
|
9
9
|
else
|
10
10
|
raise ActiveRecord::RecordNotFound, "Can't find snippet: #{slug}"
|
@@ -2,14 +2,18 @@ module OpenConferenceWare
|
|
2
2
|
module UserFavoritesHelper
|
3
3
|
# Add JavaScript to layout that populates the user's favorites and binds these controls.
|
4
4
|
def include_user_favorites_javascript
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
if user_favorites?
|
6
|
+
expose_to_js :favorites_path, user_favorites_path(user_id: :me)
|
7
|
+
run_when_dom_is_ready 'populate_user_favorites();'
|
8
|
+
run_when_dom_is_ready 'bind_user_favorite_controls();'
|
9
|
+
end
|
8
10
|
end
|
9
11
|
|
10
12
|
# Return link for a UserFavorite control for the given +proposal+.
|
11
13
|
def user_favorite_control_for(proposal)
|
12
|
-
|
14
|
+
if user_favorites?
|
15
|
+
return link_to(content_tag(:span, "*"), user_favorites_path(:me), class: "favorite favorite_#{proposal.id}")
|
16
|
+
end
|
13
17
|
end
|
14
18
|
end
|
15
19
|
end
|
@@ -27,12 +27,8 @@ module OpenConferenceWare
|
|
27
27
|
|
28
28
|
class Event < OpenConferenceWare::Base
|
29
29
|
# Mixins
|
30
|
-
### Provide cached Snippet.lookup(id) method.
|
31
|
-
include CacheLookupsMixin
|
32
30
|
include SimpleSlugMixin
|
33
31
|
|
34
|
-
cache_lookups_for :slug, order: 'deadline desc', include: [:tracks, :rooms]
|
35
|
-
|
36
32
|
# Associations
|
37
33
|
has_many :proposals, dependent: :destroy
|
38
34
|
has_many :tracks, dependent: :destroy
|
@@ -86,10 +82,7 @@ module OpenConferenceWare
|
|
86
82
|
# see if a snippet says which is current, else tries to return the event
|
87
83
|
# with the latest deadline, else returns a nil.
|
88
84
|
def self.current
|
89
|
-
|
90
|
-
return self.cache_lookups? ?
|
91
|
-
self.fetch_object('event_current', &query) :
|
92
|
-
query.call
|
85
|
+
self.current_by_settings || self.current_by_deadline
|
93
86
|
end
|
94
87
|
|
95
88
|
# Return current event by finding it by deadline.
|
@@ -38,9 +38,6 @@ module OpenConferenceWare
|
|
38
38
|
# Provide ::event_tracks? and other methods for accessing SETTING
|
39
39
|
include SettingsCheckersMixin
|
40
40
|
|
41
|
-
# Provide ::lookup
|
42
|
-
include CacheLookupsMixin
|
43
|
-
|
44
41
|
# Provide ::overlaps?
|
45
42
|
include ScheduleOverlapsMixin
|
46
43
|
|
@@ -57,74 +54,70 @@ module OpenConferenceWare
|
|
57
54
|
:track_id, :track_title,
|
58
55
|
:user_ids, :user_titles
|
59
56
|
|
60
|
-
|
61
|
-
cache_lookups_for :id, order: 'submitted_at desc', include: [:event, :track, :room, :users]
|
62
|
-
|
63
57
|
# Provide #tags
|
64
58
|
acts_as_taggable_on :tags
|
65
59
|
|
66
60
|
# Acts As State Machine
|
67
61
|
include AASM
|
68
62
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
transitions from: :waitlisted, to: :accepted
|
86
|
-
end
|
63
|
+
aasm(column: :status) do
|
64
|
+
|
65
|
+
state :proposed, initial: true
|
66
|
+
state :accepted
|
67
|
+
state :waitlisted
|
68
|
+
state :rejected
|
69
|
+
state :confirmed
|
70
|
+
state :declined
|
71
|
+
state :junk
|
72
|
+
state :cancelled
|
73
|
+
|
74
|
+
event :accept do
|
75
|
+
transitions from: :proposed, to: :accepted
|
76
|
+
transitions from: :rejected, to: :accepted
|
77
|
+
transitions from: :waitlisted, to: :accepted
|
78
|
+
end
|
87
79
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
80
|
+
event :reject do
|
81
|
+
transitions from: :proposed, to: :rejected
|
82
|
+
transitions from: :accepted, to: :rejected
|
83
|
+
transitions from: :waitlisted, to: :rejected
|
84
|
+
end
|
93
85
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
86
|
+
event :waitlist do
|
87
|
+
transitions from: :proposed, to: :waitlisted
|
88
|
+
transitions from: :accepted, to: :waitlisted
|
89
|
+
transitions from: :rejected, to: :waitlisted
|
90
|
+
end
|
99
91
|
|
100
|
-
|
101
|
-
|
102
|
-
|
92
|
+
event :confirm do
|
93
|
+
transitions from: :accepted, to: :confirmed
|
94
|
+
end
|
103
95
|
|
104
|
-
|
105
|
-
|
106
|
-
|
96
|
+
event :decline do
|
97
|
+
transitions from: :accepted, to: :declined
|
98
|
+
end
|
107
99
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
100
|
+
event :accept_and_confirm do
|
101
|
+
transitions from: :proposed, to: :confirmed
|
102
|
+
transitions from: :waitlisted, to: :confirmed
|
103
|
+
end
|
112
104
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
105
|
+
event :accept_and_decline do
|
106
|
+
transitions from: :proposed, to: :declined
|
107
|
+
transitions from: :waitlisted, to: :declined
|
108
|
+
end
|
117
109
|
|
118
|
-
|
119
|
-
|
120
|
-
|
110
|
+
event :mark_as_junk do
|
111
|
+
transitions from: :proposed, to: :junk
|
112
|
+
end
|
121
113
|
|
122
|
-
|
123
|
-
|
124
|
-
|
114
|
+
event :reset_status do
|
115
|
+
transitions from: %w(accepted rejected waitlisted confirmed declined junk cancelled), to: :proposed
|
116
|
+
end
|
125
117
|
|
126
|
-
|
127
|
-
|
118
|
+
event :cancel do
|
119
|
+
transitions from: :confirmed, to: :cancelled
|
120
|
+
end
|
128
121
|
end
|
129
122
|
|
130
123
|
# Associations
|
@@ -162,8 +155,8 @@ module OpenConferenceWare
|
|
162
155
|
validates_presence_of :session_type, if: :event_session_types?
|
163
156
|
validates_presence_of :presenter, :email, :biography, unless: :user_profiles?
|
164
157
|
validates_presence_of :speaking_experience, if: :proposal_speaking_experience?
|
165
|
-
validates_presence_of :audience_level, if: Proc.new { Proposal.audience_levels }
|
166
|
-
validates_inclusion_of :audience_level, if: Proc.new { Proposal.audience_levels }, allow_blank: true,
|
158
|
+
validates_presence_of :audience_level, if: Proc.new { Proposal.audience_levels.present? }
|
159
|
+
validates_inclusion_of :audience_level, if: Proc.new { Proposal.audience_levels.present? }, allow_blank: true,
|
167
160
|
in: OpenConferenceWare.proposal_audience_levels ?
|
168
161
|
OpenConferenceWare.proposal_audience_levels.flatten.map { |level| level.with_indifferent_access['slug'] } :
|
169
162
|
[]
|
@@ -268,15 +261,15 @@ module OpenConferenceWare
|
|
268
261
|
# representing optional states. Of each pair, the first element is the title,
|
269
262
|
# the second is the status.
|
270
263
|
def titles_and_statuses
|
271
|
-
result = [["(currently '#{self.
|
272
|
-
result += self.
|
264
|
+
result = [["(currently '#{self.aasm.current_state.to_s.titleize}')", nil]]
|
265
|
+
result += self.aasm.events(aasm.current_state).map{|s|[s.to_s.titleize, s.to_s]}.sort_by{|title, state| title}
|
273
266
|
return result
|
274
267
|
end
|
275
268
|
|
276
269
|
# allows an interface to state machine through update_attributes transition key
|
277
270
|
attr_accessor :transition
|
278
271
|
def transition=(event)
|
279
|
-
send("#{event}!") if !event.blank? &&
|
272
|
+
send("#{event}!") if !event.blank? && aasm.events(aasm.current_state).include?(event.to_sym)
|
280
273
|
end
|
281
274
|
|
282
275
|
# Is this +user+ allowed to alter this proposal?
|