Create restful invites controller and ajaxified the workflow.
This commit is contained in:
parent
5cf75ee32a
commit
178fba7b30
11 changed files with 89 additions and 52 deletions
|
@ -1,20 +0,0 @@
|
||||||
class FoodcoopController < ApplicationController
|
|
||||||
|
|
||||||
before_filter :authenticate_membership_or_admin
|
|
||||||
|
|
||||||
# Invites a new user to join foodsoft in this group.
|
|
||||||
def invite
|
|
||||||
@invite = Invite.new
|
|
||||||
end
|
|
||||||
|
|
||||||
# Sends an email
|
|
||||||
def send_invitation
|
|
||||||
@invite = Invite.new(:user => @current_user, :group => @group, :email => params[:invite][:email])
|
|
||||||
if @invite.save
|
|
||||||
flash[:notice] = format('Es wurde eine Einladung an %s geschickt.', @invite.email)
|
|
||||||
redirect_to root_path
|
|
||||||
else
|
|
||||||
render :action => 'invite'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
26
app/controllers/invites_controller.rb
Normal file
26
app/controllers/invites_controller.rb
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
class InvitesController < ApplicationController
|
||||||
|
|
||||||
|
before_filter :authenticate_membership_or_admin, :only => [:new]
|
||||||
|
#TODO: auhtorize also for create action.
|
||||||
|
|
||||||
|
def new
|
||||||
|
@invite = Invite.new(:user => @current_user, :group => @group)
|
||||||
|
|
||||||
|
render :update do |page|
|
||||||
|
page.replace_html :edit_box, :partial => "new"
|
||||||
|
page.show :edit_box
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@invite = Invite.new(params[:invite])
|
||||||
|
|
||||||
|
render :update do |page|
|
||||||
|
if @invite.save
|
||||||
|
page.replace_html :edit_box, :partial => "success"
|
||||||
|
else
|
||||||
|
page.replace_html :edit_box, :partial => "new"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -23,9 +23,7 @@ class Invite < ActiveRecord::Base
|
||||||
validates_presence_of :group
|
validates_presence_of :group
|
||||||
validates_presence_of :token
|
validates_presence_of :token
|
||||||
validates_presence_of :expires_at
|
validates_presence_of :expires_at
|
||||||
|
|
||||||
attr_accessible :email, :user, :group
|
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
# Before validation, set token and expires_at.
|
# Before validation, set token and expires_at.
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
- title "Neues Foodcoop-Mitglied einladen"
|
|
||||||
|
|
||||||
%p
|
|
||||||
Hier kannst du eine Person in die Gruppe
|
|
||||||
%b=h @group.name
|
|
||||||
einladen, die noch nicht Mitglied der Foodcoop ist.
|
|
||||||
.edit_form{:style => 'width:35em'}
|
|
||||||
- form_for(@invite, :url => {:action => 'send_invitation', :id => @group}) do |form|
|
|
||||||
= form.error_messages
|
|
||||||
%p
|
|
||||||
Email-Adresse:
|
|
||||||
= form.text_field('email', :size => 40, :maxlength => 128)
|
|
||||||
%p
|
|
||||||
= submit_tag('Einladung abschicken')
|
|
16
app/views/invites/_new.html.haml
Normal file
16
app/views/invites/_new.html.haml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
%p
|
||||||
|
Hier kannst du eine Person in die Gruppe
|
||||||
|
%b=h @invite.group.name
|
||||||
|
einladen, die noch nicht Mitglied der Foodcoop ist.
|
||||||
|
.edit_form{:style => 'width:35em'}
|
||||||
|
- remote_form_for @invite do |form|
|
||||||
|
= form.error_messages :header_message => nil
|
||||||
|
= form.hidden_field :user_id
|
||||||
|
= form.hidden_field :group_id
|
||||||
|
%p
|
||||||
|
Email-Adresse:
|
||||||
|
= form.text_field :email, :size => 40, :maxlength => 128
|
||||||
|
%p
|
||||||
|
= submit_tag('Einladung abschicken')
|
||||||
|
oder
|
||||||
|
= link_to_function "Abbrechen", "Element.hide('edit_box')"
|
7
app/views/invites/_success.html.haml
Normal file
7
app/views/invites/_success.html.haml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
%p
|
||||||
|
%b= @invite.email
|
||||||
|
wurde erfolgreich eingeladen.
|
||||||
|
%p
|
||||||
|
= link_to_function "Schließen", "Element.hide('edit_box')"
|
||||||
|
oder
|
||||||
|
= remote_link_to "Weitere Person einladen", :url => new_invite_path(:id => @invite.group)
|
|
@ -2,7 +2,7 @@
|
||||||
<p>
|
<p>
|
||||||
<i>
|
<i>
|
||||||
Hier kannst Du die Mitglieder der Gruppe verwalten oder ein neues Foodcoop-Mitglied in die Gruppe
|
Hier kannst Du die Mitglieder der Gruppe verwalten oder ein neues Foodcoop-Mitglied in die Gruppe
|
||||||
<%= link_to('einladen', :controller => '/foodcoop', :action => 'invite', :id => @group) %>.
|
<%= remote_link_to('einladen', :url => new_invite_path(:id => @group)) %>.
|
||||||
</i>
|
</i>
|
||||||
</p>
|
</p>
|
||||||
<div class="left_column" style="width:48%">
|
<div class="left_column" style="width:48%">
|
||||||
|
@ -22,3 +22,5 @@
|
||||||
<%= link_to('Person einladen', :controller => '/foodcoop', :action => 'invite', :id => @group) %>
|
<%= link_to('Person einladen', :controller => '/foodcoop', :action => 'invite', :id => @group) %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="edit_box" style="display:none"></div>
|
||||||
|
|
|
@ -10,6 +10,8 @@ ActionController::Routing::Routes.draw do |map|
|
||||||
map.resources :messages, :only => [:index, :show, :new, :create],
|
map.resources :messages, :only => [:index, :show, :new, :create],
|
||||||
:member => { :reply => :get, :user => :get, :group => :get }
|
:member => { :reply => :get, :user => :get, :group => :get }
|
||||||
|
|
||||||
|
map.resources :invites, :only => [:new, :create]
|
||||||
|
|
||||||
map.namespace :foodcoop do |foodcoop|
|
map.namespace :foodcoop do |foodcoop|
|
||||||
foodcoop.root :controller => "users", :action => "index"
|
foodcoop.root :controller => "users", :action => "index"
|
||||||
foodcoop.resources :users, :only => [:index]
|
foodcoop.resources :users, :only => [:index]
|
||||||
|
|
|
@ -161,31 +161,31 @@ span.click-me {
|
||||||
background: #f5f5f5;
|
background: #f5f5f5;
|
||||||
padding: 0 10px 0px 5px;
|
padding: 0 10px 0px 5px;
|
||||||
float: left; }
|
float: left; }
|
||||||
.menu ul, #start_nav ul {
|
.menu ul, #start_nav ul {
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
margin: 0 0 0.2em 0;
|
margin: 0 0 0.2em 0;
|
||||||
padding: 0; }
|
padding: 0; }
|
||||||
.menu ul li, #start_nav ul li {
|
.menu ul li, #start_nav ul li {
|
||||||
border-bottom: 1px solid #dedede;
|
border-bottom: 1px solid #dedede;
|
||||||
color: #666;
|
color: #666;
|
||||||
margin: 0.8em 0 0 0;
|
margin: 0.8em 0 0 0;
|
||||||
font-weight: bold; }
|
font-weight: bold; }
|
||||||
.menu ul li a:link, .menu ul li a:visited, #start_nav ul li a:link, #start_nav ul li a:visited {
|
.menu ul li a:link, .menu ul li a:visited, #start_nav ul li a:link, #start_nav ul li a:visited {
|
||||||
display: block;
|
display: block;
|
||||||
padding: 0.25em 1em;
|
padding: 0.25em 1em;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
width: 12em; }
|
width: 12em; }
|
||||||
.menu ul li a:hover, .menu ul li a:focus, #start_nav ul li a:hover, #start_nav ul li a:focus {
|
.menu ul li a:hover, .menu ul li a:focus, #start_nav ul li a:hover, #start_nav ul li a:focus {
|
||||||
background-color: #e3e3e3; }
|
background-color: #e3e3e3; }
|
||||||
.menu ul li ul, #start_nav ul li ul {
|
.menu ul li ul, #start_nav ul li ul {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0; }
|
padding: 0; }
|
||||||
.menu ul li ul li, #start_nav ul li ul li {
|
.menu ul li ul li, #start_nav ul li ul li {
|
||||||
border-top: 1px solid #dedede;
|
border-top: 1px solid #dedede;
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-weight: normal; }
|
font-weight: normal; }
|
||||||
.menu ul li ul li a:link, .menu ul li ul li a:visited, #start_nav ul li ul li a:link, #start_nav ul li ul li a:visited {
|
.menu ul li ul li a:link, .menu ul li ul li a:visited, #start_nav ul li ul li a:link, #start_nav ul li ul li a:visited {
|
||||||
width: 11.5em;
|
width: 11.5em;
|
||||||
padding: 0 1em 0.1em 1.5em;
|
padding: 0 1em 0.1em 1.5em;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
|
|
|
@ -161,31 +161,31 @@ span.click-me {
|
||||||
background: #f5f5f5;
|
background: #f5f5f5;
|
||||||
padding: 0 10px 0px 5px;
|
padding: 0 10px 0px 5px;
|
||||||
float: left; }
|
float: left; }
|
||||||
.menu ul, #start_nav ul {
|
.menu ul, #start_nav ul {
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
margin: 0 0 0.2em 0;
|
margin: 0 0 0.2em 0;
|
||||||
padding: 0; }
|
padding: 0; }
|
||||||
.menu ul li, #start_nav ul li {
|
.menu ul li, #start_nav ul li {
|
||||||
border-bottom: 1px solid #dedede;
|
border-bottom: 1px solid #dedede;
|
||||||
color: #666;
|
color: #666;
|
||||||
margin: 0.8em 0 0 0;
|
margin: 0.8em 0 0 0;
|
||||||
font-weight: bold; }
|
font-weight: bold; }
|
||||||
.menu ul li a:link, .menu ul li a:visited, #start_nav ul li a:link, #start_nav ul li a:visited {
|
.menu ul li a:link, .menu ul li a:visited, #start_nav ul li a:link, #start_nav ul li a:visited {
|
||||||
display: block;
|
display: block;
|
||||||
padding: 0.25em 1em;
|
padding: 0.25em 1em;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
width: 12em; }
|
width: 12em; }
|
||||||
.menu ul li a:hover, .menu ul li a:focus, #start_nav ul li a:hover, #start_nav ul li a:focus {
|
.menu ul li a:hover, .menu ul li a:focus, #start_nav ul li a:hover, #start_nav ul li a:focus {
|
||||||
background-color: #e3e3e3; }
|
background-color: #e3e3e3; }
|
||||||
.menu ul li ul, #start_nav ul li ul {
|
.menu ul li ul, #start_nav ul li ul {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0; }
|
padding: 0; }
|
||||||
.menu ul li ul li, #start_nav ul li ul li {
|
.menu ul li ul li, #start_nav ul li ul li {
|
||||||
border-top: 1px solid #dedede;
|
border-top: 1px solid #dedede;
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-weight: normal; }
|
font-weight: normal; }
|
||||||
.menu ul li ul li a:link, .menu ul li ul li a:visited, #start_nav ul li ul li a:link, #start_nav ul li ul li a:visited {
|
.menu ul li ul li a:link, .menu ul li ul li a:visited, #start_nav ul li ul li a:link, #start_nav ul li ul li a:visited {
|
||||||
width: 11.5em;
|
width: 11.5em;
|
||||||
padding: 0 1em 0.1em 1.5em;
|
padding: 0 1em 0.1em 1.5em;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
|
|
20
test/functional/invites_controller_test.rb
Normal file
20
test/functional/invites_controller_test.rb
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
require 'test_helper'
|
||||||
|
|
||||||
|
class InvitesControllerTest < ActionController::TestCase
|
||||||
|
def test_new
|
||||||
|
get :new
|
||||||
|
assert_template 'new'
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_create_invalid
|
||||||
|
Invite.any_instance.stubs(:valid?).returns(false)
|
||||||
|
post :create
|
||||||
|
assert_template 'new'
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_create_valid
|
||||||
|
Invite.any_instance.stubs(:valid?).returns(true)
|
||||||
|
post :create
|
||||||
|
assert_redirected_to root_url
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue