rsvp 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/MIT-LICENSE +20 -0
- data/Rakefile +26 -0
- data/app/assets/javascripts/rsvp/application.js +15 -0
- data/app/assets/javascripts/rsvp/response_tabs.js +22 -0
- data/app/assets/stylesheets/rsvp/application.css +13 -0
- data/app/controllers/rsvp/application_controller.rb +17 -0
- data/app/controllers/rsvp/response_controller.rb +33 -0
- data/app/controllers/rsvp/session_controller.rb +26 -0
- data/app/helpers/rsvp/application_helper.rb +4 -0
- data/app/models/rsvp/family.rb +9 -0
- data/app/models/rsvp/invitation.rb +14 -0
- data/app/models/rsvp/member.rb +6 -0
- data/app/models/rsvp/person/adult_female.rb +4 -0
- data/app/models/rsvp/person/adult_male.rb +4 -0
- data/app/models/rsvp/person/young_female.rb +4 -0
- data/app/models/rsvp/person/young_male.rb +4 -0
- data/app/models/rsvp/person.rb +20 -0
- data/app/models/rsvp/response.rb +30 -0
- data/app/models/rsvp/salutation/husband_and_wife.rb +10 -0
- data/app/models/rsvp/salutation/husband_wife_and_family.rb +10 -0
- data/app/models/rsvp/salutation/lieutenant_colonel_and_wife.rb +10 -0
- data/app/models/rsvp/salutation/male_doctor_and_wife.rb +10 -0
- data/app/models/rsvp/salutation/single_female.rb +10 -0
- data/app/models/rsvp/salutation/single_female_and_guest.rb +10 -0
- data/app/models/rsvp/salutation/single_male.rb +10 -0
- data/app/models/rsvp/salutation/single_male_and_guest.rb +10 -0
- data/app/models/rsvp/salutation/widow.rb +10 -0
- data/app/models/rsvp/salutation/widow_and_family.rb +10 -0
- data/app/models/rsvp/salutation/widower.rb +10 -0
- data/app/models/rsvp/salutation/widower_and_family.rb +10 -0
- data/app/models/rsvp/salutation.rb +25 -0
- data/app/views/layouts/rsvp/application.html.erb +21 -0
- data/app/views/rsvp/response/_show.html.erb +10 -0
- data/app/views/rsvp/response/confirmation.html.erb +7 -0
- data/app/views/rsvp/response/index.html.erb +47 -0
- data/app/views/rsvp/response/show.html.erb +4 -0
- data/app/views/rsvp/session/index.html.erb +5 -0
- data/config/cucumber.yml +8 -0
- data/config/routes.rb +12 -0
- data/db/migrate/20140106042028_create_rsvp_people.rb +12 -0
- data/db/migrate/20140106042630_create_rsvp_families.rb +13 -0
- data/db/migrate/20140106042748_create_rsvp_members.rb +10 -0
- data/db/migrate/20140106042845_create_rsvp_invitations.rb +13 -0
- data/db/migrate/20140106043014_create_rsvp_responses.rb +12 -0
- data/db/migrate/20140106043143_create_rsvp_salutations.rb +10 -0
- data/lib/generators/rsvp/USAGE +12 -0
- data/lib/generators/rsvp/views_generator.rb +13 -0
- data/lib/rsvp/engine.rb +20 -0
- data/lib/rsvp/version.rb +3 -0
- data/lib/rsvp.rb +4 -0
- data/lib/tasks/cucumber.rake +63 -0
- data/lib/tasks/rsvp_tasks.rake +4 -0
- metadata +231 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
ZDYyNWQzMTk3MzVlYTM5MWQ5YWQwMWI0YWU2ZTRmODdmN2NlMDdhNA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
ZjBjYjFjYjBiMTM3MmQ3NWZlMTczNTk3N2U2YmJkMDdhZmU3ZTQ0NQ==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
YzIxMDQzZDQyZjZlMmVhZjRiNmFiMmUwNzQ3ZDFhYzg1M2EzMTc1NmJmNGVl
|
10
|
+
ZDFhM2UwNTZlNTQ3OWQ5YWYxZTg2ODJhNTM0ODI4ZmE5OTE0ZmUxOTM1OGEw
|
11
|
+
Y2NlMmEzYzEzNTFiMDIzMjZmMzAwNGY3YzUyYWUzOTNlMDAwMmQ=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
YTgyOTgyZWYyMTRhNDlmOTQyNDgyZWMzOTVmOTIxODFhNzA0ZDAyOTQ1NDJk
|
14
|
+
OTY2N2I1NGNiZDlmZTJjZDI0NzNhYzQ2ZTFkY2QxODRhOWU2MGYxZWNiM2Jm
|
15
|
+
MDViM2VhNjI0NzZiMjdkYzg1MDUzN2YwNTdjNDFhYjJhMTdlN2I=
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2014 Ryan Ricard
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'Rsvp'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.rdoc')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
|
18
|
+
load 'rails/tasks/engine.rake'
|
19
|
+
|
20
|
+
Bundler::GemHelper.install_tasks
|
21
|
+
|
22
|
+
# Run rspec as default task
|
23
|
+
# more info here: https://www.relishapp.com/rspec/rspec-core/docs/command-line/rake-task
|
24
|
+
require 'rspec/core/rake_task'
|
25
|
+
RSpec::Core::RakeTask.new(:spec)
|
26
|
+
task :default => :spec
|
@@ -0,0 +1,15 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
+
// listed below.
|
3
|
+
//
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
+
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
|
6
|
+
//
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
+
// compiled file.
|
9
|
+
//
|
10
|
+
// Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
|
11
|
+
// about supported directives.
|
12
|
+
//
|
13
|
+
//= require jquery
|
14
|
+
//= require jquery_ujs
|
15
|
+
// require_tree .
|
@@ -0,0 +1,22 @@
|
|
1
|
+
$(function(){
|
2
|
+
(function(){
|
3
|
+
var _tabs, _containers;
|
4
|
+
var show = function(tab){
|
5
|
+
_tabs.removeClass("active");
|
6
|
+
_containers.hide();
|
7
|
+
tab.addClass("active");
|
8
|
+
$(tab.data("container")).show();
|
9
|
+
};
|
10
|
+
return {
|
11
|
+
init: function(tabs, containers){
|
12
|
+
_tabs = tabs;
|
13
|
+
_containers = containers.hide();
|
14
|
+
tabs.click(function(e){
|
15
|
+
var tab = $(e.target);
|
16
|
+
show(tab);
|
17
|
+
});
|
18
|
+
$(".tab.active").click();
|
19
|
+
}
|
20
|
+
};
|
21
|
+
})().init($(".tab"), $(".container"));
|
22
|
+
});
|
@@ -0,0 +1,13 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the top of the
|
9
|
+
* compiled file, but it's generally better to create a new file per style scope.
|
10
|
+
*
|
11
|
+
*= require_self
|
12
|
+
*= require_tree .
|
13
|
+
*/
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Rsvp
|
2
|
+
class ApplicationController < ActionController::Base
|
3
|
+
protect_from_forgery
|
4
|
+
|
5
|
+
before_filter :require_session
|
6
|
+
|
7
|
+
private
|
8
|
+
|
9
|
+
def require_session
|
10
|
+
unless session[:invitation_id]
|
11
|
+
flash[:alert] = "You must begin a RSVP session to access that page."
|
12
|
+
redirect_to root_path
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Rsvp
|
2
|
+
class ResponseController < ApplicationController
|
3
|
+
before_filter :prepare_instance_vars, :only => [:index, :show, :confirmation]
|
4
|
+
|
5
|
+
# GET /response
|
6
|
+
def index; end
|
7
|
+
|
8
|
+
# POST /response
|
9
|
+
def create
|
10
|
+
@invitation = Invitation.find(session[:invitation_id])
|
11
|
+
@response = @invitation.responses.build(params[:response])
|
12
|
+
if @response.save
|
13
|
+
redirect_to confirmation_response_index_path
|
14
|
+
else
|
15
|
+
render :action => :index
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# GET /response/overview
|
20
|
+
def show; end
|
21
|
+
|
22
|
+
# GET /response/confirmation
|
23
|
+
def confirmation; end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def prepare_instance_vars
|
28
|
+
@invitation = Invitation.find(session[:invitation_id])
|
29
|
+
@invitation.responses.build unless @invitation.responses.any?
|
30
|
+
@response = @invitation.responses.last
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Rsvp
|
2
|
+
class SessionController < ApplicationController
|
3
|
+
skip_before_filter :require_session, :only => [:index, :create]
|
4
|
+
|
5
|
+
# GET /session
|
6
|
+
def index; end
|
7
|
+
|
8
|
+
# POST /session
|
9
|
+
def create
|
10
|
+
invitation = Invitation.find_by_rsvp_code(params[:rsvp_code])
|
11
|
+
if invitation
|
12
|
+
session[:invitation_id] = invitation.id
|
13
|
+
redirect_to (invitation.responses.any? ? show_response_index_path : response_index_path)
|
14
|
+
else
|
15
|
+
flash.alert = "Oops!! The code you entered is not valid. Please try again."
|
16
|
+
redirect_to root_path
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# DELETE /session
|
21
|
+
def destroy
|
22
|
+
session[:invitation_id] = nil
|
23
|
+
redirect_to root_path, notice: "Thank you for your response!"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Rsvp
|
2
|
+
class Invitation < ActiveRecord::Base
|
3
|
+
attr_accessible :rsvp_code, :total_invited
|
4
|
+
belongs_to :family
|
5
|
+
has_many :responses
|
6
|
+
|
7
|
+
validates :rsvp_code, :presence => true, :uniqueness => true, :length => { is: 7 }
|
8
|
+
validates :total_invited, :inclusion => 1..10
|
9
|
+
|
10
|
+
def total_invite_options
|
11
|
+
(1..total_invited).to_a
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Rsvp
|
2
|
+
class Person < ActiveRecord::Base
|
3
|
+
self.inheritance_column = :gender
|
4
|
+
attr_accessible :first_name, :gender, :last_name, :suffix
|
5
|
+
has_many :memberships, :class_name => "Member"
|
6
|
+
has_many :families, :through => :memberships
|
7
|
+
|
8
|
+
validates :first_name, :presence => true
|
9
|
+
validates :last_name, :presence => true
|
10
|
+
|
11
|
+
|
12
|
+
def self.adult_males
|
13
|
+
where("gender = ?", Person::AdultMale.to_s)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.adult_females
|
17
|
+
where("gender = ?", Person::AdultFemale.to_s)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Rsvp
|
2
|
+
class Response < ActiveRecord::Base
|
3
|
+
attr_accessible :comment, :email, :total_attending
|
4
|
+
belongs_to :invitation
|
5
|
+
|
6
|
+
validates :total_attending, :presence => true
|
7
|
+
validate :validate_total_attending
|
8
|
+
validate :validate_email_if_entered
|
9
|
+
|
10
|
+
def validate_total_attending
|
11
|
+
if invitation.total_invited < total_attending.to_i
|
12
|
+
errors.add(:total_attending, "cannot be greater than total invited")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def validate_email_if_entered
|
17
|
+
if email.present? && !email.match(/^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i)
|
18
|
+
errors.add(:email, "is invalid")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def is_yes?
|
23
|
+
total_attending.to_i > 0
|
24
|
+
end
|
25
|
+
|
26
|
+
def is_no?
|
27
|
+
total_attending.to_i == 0 && !total_attending.nil?
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Rsvp
|
2
|
+
class Salutation < ActiveRecord::Base
|
3
|
+
attr_accessible :type
|
4
|
+
belongs_to :family
|
5
|
+
|
6
|
+
def template
|
7
|
+
raise "Template not implemented in subclass."
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_s
|
11
|
+
merge
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def merge
|
17
|
+
salutation = template
|
18
|
+
template.scan(/\[\[\w*\]\]/).each do |expression|
|
19
|
+
salutation_method, person_method = expression.tr("][", "").split(/__/)
|
20
|
+
salutation.gsub!(expression, send(salutation_method).send(person_method))
|
21
|
+
end
|
22
|
+
salutation
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>RSVP</title>
|
5
|
+
<%= stylesheet_link_tag "rsvp/application", media: "all" %>
|
6
|
+
<%= javascript_include_tag "rsvp/application" %>
|
7
|
+
<%= csrf_meta_tags %>
|
8
|
+
</head>
|
9
|
+
<body>
|
10
|
+
<% if notice %>
|
11
|
+
<p><%= notice %></p>
|
12
|
+
<% end %>
|
13
|
+
|
14
|
+
<% if alert %>
|
15
|
+
<p><%= alert %></p>
|
16
|
+
<% end %>
|
17
|
+
|
18
|
+
<%= yield %>
|
19
|
+
|
20
|
+
</body>
|
21
|
+
</html>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<% if @response.is_yes? %>
|
2
|
+
<%= "Total attending: " + @response.total_attending.to_s %>
|
3
|
+
<%= "Email: " + @response.email.html_safe %>
|
4
|
+
<%= "Comment: " + @response.comment.html_safe %>
|
5
|
+
<% else %>
|
6
|
+
<p>No, I will not be attending.</p>
|
7
|
+
<% end %>
|
8
|
+
|
9
|
+
<%= link_to "Change my response", response_index_path %>
|
10
|
+
<%= link_to "I'm done!", sign_out_path %>
|
@@ -0,0 +1,47 @@
|
|
1
|
+
<% if @response.errors.any? %>
|
2
|
+
<% @response.errors.full_messages.each do |msg| %>
|
3
|
+
<ul>
|
4
|
+
<li><%= msg %></li>
|
5
|
+
</ul>
|
6
|
+
<% end %>
|
7
|
+
<% end %>
|
8
|
+
|
9
|
+
<p>Hi, <%= @invitation.family.salutation %>! Thank you for choosing to RSVP to our special day.</p>
|
10
|
+
<p>Will you attend?</p>
|
11
|
+
|
12
|
+
<ul>
|
13
|
+
<li><a href="#" data-container="#yes-container" class="tab <%= 'active' if @response.is_yes? || @response.errors.any? %>">Yes</a></li>
|
14
|
+
<li><a href="#" data-container="#no-container" class="tab <%= 'active' if @response.is_no? %>">No</a></li>
|
15
|
+
</ul>
|
16
|
+
|
17
|
+
<div id="yes-container" class="container">
|
18
|
+
<%= form_for @invitation, :url => response_index_path, :method => :post do |f| %>
|
19
|
+
<%= fields_for @response do |r| %>
|
20
|
+
<% if @invitation.total_invited > 1 %>
|
21
|
+
<%= r.label :total_attending %>
|
22
|
+
<%= r.select :total_attending, @invitation.total_invite_options, :include_blank => true %>
|
23
|
+
<% else %>
|
24
|
+
<%= r.hidden_field :total_attending, value: @invitation.total_invited %>
|
25
|
+
<% end %>
|
26
|
+
<%= r.label :email %>
|
27
|
+
<%= r.text_field :email %>
|
28
|
+
<%= r.label :comment %>
|
29
|
+
<%= r.text_area :comment %>
|
30
|
+
<% end %>
|
31
|
+
<%= f.button "Cancel", :type => :button %>
|
32
|
+
<%= f.submit "Submit RSVP" %>
|
33
|
+
<% end %>
|
34
|
+
</div>
|
35
|
+
|
36
|
+
<div id="no-container" class="container">
|
37
|
+
<%= form_for @invitation, :url => response_index_path, :method => :post do |f| %>
|
38
|
+
<%= fields_for @response do |r| %>
|
39
|
+
<%= r.hidden_field :total_attending, value: 0 %>
|
40
|
+
<% end %>
|
41
|
+
<p>No, I will not be attending.</p>
|
42
|
+
<%= f.button "Cancel", :type => :button %>
|
43
|
+
<%= f.submit "Submit RSVP" %>
|
44
|
+
<% end %>
|
45
|
+
</div>
|
46
|
+
|
47
|
+
<%= javascript_include_tag "rsvp/response_tabs.js" %>
|
data/config/cucumber.yml
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
<%
|
2
|
+
rerun = File.file?('rerun.txt') ? IO.read('rerun.txt') : ""
|
3
|
+
rerun_opts = rerun.to_s.strip.empty? ? "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} features" : "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} #{rerun}"
|
4
|
+
std_opts = "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} --strict --tags ~@wip"
|
5
|
+
%>
|
6
|
+
default: <%= std_opts %> features
|
7
|
+
wip: --tags @wip:3 --wip features
|
8
|
+
rerun: <%= rerun_opts %> --format rerun --out rerun.txt --strict --tags ~@wip
|
data/config/routes.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
Rsvp::Engine.routes.draw do
|
2
|
+
root :to => "session#index"
|
3
|
+
get :sign_in, :controller => :session, :action => :index
|
4
|
+
post :sign_in, :controller => :session, :action => :create
|
5
|
+
get :sign_out, :controller => :session, :action => :destroy
|
6
|
+
resources :response, :only => [:index, :create] do
|
7
|
+
collection do
|
8
|
+
get :overview, :action => :show, :as => :show
|
9
|
+
get :confirmation, :action => :confirmation
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class CreateRsvpPeople < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :rsvp_people do |t|
|
4
|
+
t.string :gender, :limit => 50
|
5
|
+
t.string :first_name, :limit => 50
|
6
|
+
t.string :last_name, :limit => 50
|
7
|
+
t.string :suffix, :limit => 15
|
8
|
+
|
9
|
+
t.timestamps
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class CreateRsvpFamilies < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :rsvp_families do |t|
|
4
|
+
t.string :street_1, :limit => 75
|
5
|
+
t.string :street_2, :limit => 75
|
6
|
+
t.string :city, :limit => 50
|
7
|
+
t.string :state, :limit => 25
|
8
|
+
t.string :postal_code, :limit => 15
|
9
|
+
|
10
|
+
t.timestamps
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class CreateRsvpInvitations < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :rsvp_invitations do |t|
|
4
|
+
t.integer :family_id
|
5
|
+
t.string :rsvp_code, :limit => 20
|
6
|
+
t.integer :total_invited
|
7
|
+
|
8
|
+
t.timestamps
|
9
|
+
end
|
10
|
+
|
11
|
+
add_index :rsvp_invitations, :rsvp_code, :unique => true
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
Description:
|
2
|
+
Copies all Rsvp views to your application.
|
3
|
+
|
4
|
+
Example:
|
5
|
+
rails generate rsvp:views
|
6
|
+
|
7
|
+
This will create:
|
8
|
+
app/views/rsvp/response/edit.html.erb
|
9
|
+
app/views/rsvp/response/index.html.erb
|
10
|
+
app/views/rsvp/response/no_confirmation.html.erb
|
11
|
+
app/views/rsvp/response/yes_confirmation.html.erb
|
12
|
+
app/views/rsvp/shared/_error_messages.html.erb
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'rails/generators/base'
|
2
|
+
|
3
|
+
module Rsvp
|
4
|
+
class ViewsGenerator < ::Rails::Generators::Base
|
5
|
+
source_root File.expand_path("../../../", __FILE__)
|
6
|
+
|
7
|
+
desc "Copies all Rsvp views to your application."
|
8
|
+
def copy_views
|
9
|
+
directory "#{Rsvp::Engine.root}/app/views/layouts/rsvp", "#{Rails.root}/app/views/layouts/rsvp/."
|
10
|
+
directory "#{Rsvp::Engine.root}/app/views/rsvp", "#{Rails.root}/app/views/rsvp/."
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/rsvp/engine.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
module Rsvp
|
2
|
+
class Engine < ::Rails::Engine
|
3
|
+
isolate_namespace Rsvp
|
4
|
+
|
5
|
+
config.generators do |g|
|
6
|
+
g.test_framework :rspec
|
7
|
+
end
|
8
|
+
|
9
|
+
# Add engine db/migrate to paths so migrations run with wrapping application
|
10
|
+
# Inspired by: http://pivotallabs.com/leave-your-migrations-in-your-rails-engines/
|
11
|
+
initializer :append_migrations do |app|
|
12
|
+
# unless app.root.to_s.match root.to_s
|
13
|
+
config.paths["db/migrate"].expanded.each do |expanded_path|
|
14
|
+
app.config.paths["db/migrate"] << expanded_path
|
15
|
+
end
|
16
|
+
# end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
data/lib/rsvp/version.rb
ADDED
data/lib/rsvp.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
# IMPORTANT: This file is generated by cucumber-rails - edit at your own peril.
|
2
|
+
# It is recommended to regenerate this file in the future when you upgrade to a
|
3
|
+
# newer version of cucumber-rails. Consider adding your own code to a new file
|
4
|
+
# instead of editing this one. Cucumber will automatically load all features/**/*.rb
|
5
|
+
# files.
|
6
|
+
unless ARGV.any? {|a| a =~ /^gems/} # Don't load anything when running the gems:* tasks
|
7
|
+
|
8
|
+
vendored_cucumber_bin = Dir["#{Rails.root}/../../vendor/bundle/gems/cucumber*/bin/cucumber"].first
|
9
|
+
$LOAD_PATH.unshift(File.dirname(vendored_cucumber_bin) + '/../lib') unless vendored_cucumber_bin.nil?
|
10
|
+
|
11
|
+
begin
|
12
|
+
require 'cucumber/rake/task'
|
13
|
+
|
14
|
+
namespace :cucumber do
|
15
|
+
Cucumber::Rake::Task.new({:ok => 'test:prepare'}, 'Run features that should pass') do |t|
|
16
|
+
t.binary = vendored_cucumber_bin # If nil, the gem's binary is used.
|
17
|
+
t.fork = true # You may get faster startup if you set this to false
|
18
|
+
t.profile = 'default'
|
19
|
+
end
|
20
|
+
|
21
|
+
Cucumber::Rake::Task.new({:wip => 'test:prepare'}, 'Run features that are being worked on') do |t|
|
22
|
+
t.binary = vendored_cucumber_bin
|
23
|
+
t.fork = true # You may get faster startup if you set this to false
|
24
|
+
t.profile = 'wip'
|
25
|
+
end
|
26
|
+
|
27
|
+
Cucumber::Rake::Task.new({:rerun => 'test:prepare'}, 'Record failing features and run only them if any exist') do |t|
|
28
|
+
t.binary = vendored_cucumber_bin
|
29
|
+
t.fork = true # You may get faster startup if you set this to false
|
30
|
+
t.profile = 'rerun'
|
31
|
+
end
|
32
|
+
|
33
|
+
desc 'Run all features'
|
34
|
+
task :all => [:ok, :wip]
|
35
|
+
|
36
|
+
task :statsetup do
|
37
|
+
require 'rails/code_statistics'
|
38
|
+
::STATS_DIRECTORIES << %w(Cucumber\ features features) if File.exist?('features')
|
39
|
+
::CodeStatistics::TEST_TYPES << "Cucumber features" if File.exist?('features')
|
40
|
+
end
|
41
|
+
end
|
42
|
+
desc 'Alias for cucumber:ok'
|
43
|
+
task :cucumber => 'cucumber:ok'
|
44
|
+
|
45
|
+
task :default => :cucumber
|
46
|
+
|
47
|
+
task :features => :cucumber do
|
48
|
+
STDERR.puts "*** The 'features' task is deprecated. See rake -T cucumber ***"
|
49
|
+
end
|
50
|
+
|
51
|
+
# In case we don't have the generic Rails test:prepare hook, append a no-op task that we can depend upon.
|
52
|
+
task 'test:prepare' do
|
53
|
+
end
|
54
|
+
|
55
|
+
task :stats => 'cucumber:statsetup'
|
56
|
+
rescue LoadError
|
57
|
+
desc 'cucumber rake task not available (cucumber not installed)'
|
58
|
+
task :cucumber do
|
59
|
+
abort 'Cucumber rake task is not available. Be sure to install cucumber as a gem or plugin'
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
metadata
ADDED
@@ -0,0 +1,231 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rsvp
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ryan Ricard
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-02-05 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '4.0'
|
20
|
+
- - ! '>='
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 4.0.2
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '4.0'
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 4.0.2
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: sqlite3
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ~>
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
type: :development
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ~>
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: debugger
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '1.6'
|
54
|
+
- - ! '>='
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: 1.6.5
|
57
|
+
type: :development
|
58
|
+
prerelease: false
|
59
|
+
version_requirements: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ~>
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '1.6'
|
64
|
+
- - ! '>='
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: 1.6.5
|
67
|
+
- !ruby/object:Gem::Dependency
|
68
|
+
name: rspec-rails
|
69
|
+
requirement: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ~>
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '2.14'
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: 2.14.1
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ~>
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '2.14'
|
84
|
+
- - ! '>='
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: 2.14.1
|
87
|
+
- !ruby/object:Gem::Dependency
|
88
|
+
name: capybara
|
89
|
+
requirement: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '2.2'
|
94
|
+
- - ! '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 2.2.1
|
97
|
+
type: :development
|
98
|
+
prerelease: false
|
99
|
+
version_requirements: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ~>
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '2.2'
|
104
|
+
- - ! '>='
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: 2.2.1
|
107
|
+
- !ruby/object:Gem::Dependency
|
108
|
+
name: selenium-webdriver
|
109
|
+
requirement: !ruby/object:Gem::Requirement
|
110
|
+
requirements:
|
111
|
+
- - ~>
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: '2.39'
|
114
|
+
- - ! '>='
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: 2.39.0
|
117
|
+
type: :development
|
118
|
+
prerelease: false
|
119
|
+
version_requirements: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - ~>
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '2.39'
|
124
|
+
- - ! '>='
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: 2.39.0
|
127
|
+
- !ruby/object:Gem::Dependency
|
128
|
+
name: database_cleaner
|
129
|
+
requirement: !ruby/object:Gem::Requirement
|
130
|
+
requirements:
|
131
|
+
- - ~>
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '1.2'
|
134
|
+
- - ! '>='
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: 1.2.0
|
137
|
+
type: :development
|
138
|
+
prerelease: false
|
139
|
+
version_requirements: !ruby/object:Gem::Requirement
|
140
|
+
requirements:
|
141
|
+
- - ~>
|
142
|
+
- !ruby/object:Gem::Version
|
143
|
+
version: '1.2'
|
144
|
+
- - ! '>='
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: 1.2.0
|
147
|
+
description: Provides wrapping application necessary views and data structures to
|
148
|
+
capture online RSVP responses.
|
149
|
+
email:
|
150
|
+
- hi@ryanricard.com
|
151
|
+
executables: []
|
152
|
+
extensions: []
|
153
|
+
extra_rdoc_files: []
|
154
|
+
files:
|
155
|
+
- MIT-LICENSE
|
156
|
+
- Rakefile
|
157
|
+
- app/assets/javascripts/rsvp/application.js
|
158
|
+
- app/assets/javascripts/rsvp/response_tabs.js
|
159
|
+
- app/assets/stylesheets/rsvp/application.css
|
160
|
+
- app/controllers/rsvp/application_controller.rb
|
161
|
+
- app/controllers/rsvp/response_controller.rb
|
162
|
+
- app/controllers/rsvp/session_controller.rb
|
163
|
+
- app/helpers/rsvp/application_helper.rb
|
164
|
+
- app/models/rsvp/family.rb
|
165
|
+
- app/models/rsvp/invitation.rb
|
166
|
+
- app/models/rsvp/member.rb
|
167
|
+
- app/models/rsvp/person.rb
|
168
|
+
- app/models/rsvp/person/adult_female.rb
|
169
|
+
- app/models/rsvp/person/adult_male.rb
|
170
|
+
- app/models/rsvp/person/young_female.rb
|
171
|
+
- app/models/rsvp/person/young_male.rb
|
172
|
+
- app/models/rsvp/response.rb
|
173
|
+
- app/models/rsvp/salutation.rb
|
174
|
+
- app/models/rsvp/salutation/husband_and_wife.rb
|
175
|
+
- app/models/rsvp/salutation/husband_wife_and_family.rb
|
176
|
+
- app/models/rsvp/salutation/lieutenant_colonel_and_wife.rb
|
177
|
+
- app/models/rsvp/salutation/male_doctor_and_wife.rb
|
178
|
+
- app/models/rsvp/salutation/single_female.rb
|
179
|
+
- app/models/rsvp/salutation/single_female_and_guest.rb
|
180
|
+
- app/models/rsvp/salutation/single_male.rb
|
181
|
+
- app/models/rsvp/salutation/single_male_and_guest.rb
|
182
|
+
- app/models/rsvp/salutation/widow.rb
|
183
|
+
- app/models/rsvp/salutation/widow_and_family.rb
|
184
|
+
- app/models/rsvp/salutation/widower.rb
|
185
|
+
- app/models/rsvp/salutation/widower_and_family.rb
|
186
|
+
- app/views/layouts/rsvp/application.html.erb
|
187
|
+
- app/views/rsvp/response/_show.html.erb
|
188
|
+
- app/views/rsvp/response/confirmation.html.erb
|
189
|
+
- app/views/rsvp/response/index.html.erb
|
190
|
+
- app/views/rsvp/response/show.html.erb
|
191
|
+
- app/views/rsvp/session/index.html.erb
|
192
|
+
- config/cucumber.yml
|
193
|
+
- config/routes.rb
|
194
|
+
- db/migrate/20140106042028_create_rsvp_people.rb
|
195
|
+
- db/migrate/20140106042630_create_rsvp_families.rb
|
196
|
+
- db/migrate/20140106042748_create_rsvp_members.rb
|
197
|
+
- db/migrate/20140106042845_create_rsvp_invitations.rb
|
198
|
+
- db/migrate/20140106043014_create_rsvp_responses.rb
|
199
|
+
- db/migrate/20140106043143_create_rsvp_salutations.rb
|
200
|
+
- lib/generators/rsvp/USAGE
|
201
|
+
- lib/generators/rsvp/views_generator.rb
|
202
|
+
- lib/rsvp.rb
|
203
|
+
- lib/rsvp/engine.rb
|
204
|
+
- lib/rsvp/version.rb
|
205
|
+
- lib/tasks/cucumber.rake
|
206
|
+
- lib/tasks/rsvp_tasks.rake
|
207
|
+
homepage: http://github.com/ryanricard/rsvp
|
208
|
+
licenses:
|
209
|
+
- MIT
|
210
|
+
metadata: {}
|
211
|
+
post_install_message:
|
212
|
+
rdoc_options: []
|
213
|
+
require_paths:
|
214
|
+
- lib
|
215
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
216
|
+
requirements:
|
217
|
+
- - ! '>='
|
218
|
+
- !ruby/object:Gem::Version
|
219
|
+
version: '0'
|
220
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
221
|
+
requirements:
|
222
|
+
- - ! '>='
|
223
|
+
- !ruby/object:Gem::Version
|
224
|
+
version: '0'
|
225
|
+
requirements: []
|
226
|
+
rubyforge_project:
|
227
|
+
rubygems_version: 2.2.1
|
228
|
+
signing_key:
|
229
|
+
specification_version: 4
|
230
|
+
summary: Rsvp is a Rails mountable engine to collects online RSVP responses.
|
231
|
+
test_files: []
|