diff --git a/Gemfile b/Gemfile index 5b632a2..fb861ef 100644 --- a/Gemfile +++ b/Gemfile @@ -37,3 +37,6 @@ group :test do gem 'capybara', '~> 2.2.1' gem 'shoulda-matchers', '~> 2.6.0' end + +gem 'simple_form' +gem 'clearance' \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock index 716a7bc..da695d7 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -26,6 +26,7 @@ GEM thread_safe (~> 0.1) tzinfo (~> 0.3.37) arel (4.0.2) + bcrypt (3.1.7) bourbon (3.1.8) sass (>= 3.2.0) thor @@ -39,6 +40,10 @@ GEM rack (>= 1.0.0) rack-test (>= 0.5.4) xpath (~> 2.0) + clearance (1.3.0) + bcrypt + email_validator (~> 1.4) + rails (>= 3.1) coderay (1.1.0) coffee-rails (4.0.1) coffee-script (>= 2.2.0) @@ -50,6 +55,8 @@ GEM columnize (0.3.6) debugger-linecache (1.2.0) diff-lcs (1.2.5) + email_validator (1.4.0) + activemodel erubis (2.7.0) execjs (2.0.2) factory_girl (4.4.0) @@ -122,6 +129,9 @@ GEM sprockets-rails (~> 2.0) shoulda-matchers (2.6.0) activesupport (>= 3.0.0) + simple_form (3.0.1) + actionpack (>= 4.0.0, < 4.1) + activemodel (>= 4.0.0, < 4.1) slop (3.5.0) sprockets (2.11.0) hike (~> 1.2) @@ -151,6 +161,7 @@ PLATFORMS DEPENDENCIES bourbon (~> 3.1.8) capybara (~> 2.2.1) + clearance coffee-rails (~> 4.0.0) factory_girl_rails (~> 4.4.1) jquery-rails @@ -162,4 +173,5 @@ DEPENDENCIES rspec-rails (~> 2.14.2) sass-rails (~> 4.0.3) shoulda-matchers (~> 2.6.0) + simple_form uglifier (>= 1.3.0) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index d83690e..1bf0ba0 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,4 +1,5 @@ class ApplicationController < ActionController::Base + include Clearance::Controller # Prevent CSRF attacks by raising an exception. # For APIs, you may want to use :null_session instead. protect_from_forgery with: :exception diff --git a/app/controllers/pages_controller.rb b/app/controllers/pages_controller.rb new file mode 100644 index 0000000..0472131 --- /dev/null +++ b/app/controllers/pages_controller.rb @@ -0,0 +1,6 @@ +class PagesController < ApplicationController + + def index + end + +end \ No newline at end of file diff --git a/app/controllers/students_controller.rb b/app/controllers/students_controller.rb new file mode 100644 index 0000000..b95e934 --- /dev/null +++ b/app/controllers/students_controller.rb @@ -0,0 +1,56 @@ +class StudentsController < ApplicationController + def index + @students = Student.all + end + + def new + @student = Student.new + end + + def create + @student = Student.new student_params + + if @student.save + flash[:notice] = "Student Successfully Created." + + redirect_to @student + else + render "new" + end + end + + def show + @student = Student.find params[:id] + end + + def edit + @student = Student.find params[:id] + end + + def update + @student = Student.find params[:id] + if @student.update_attributes student_params + flash[:notice] = "Student Successfully Updated." + redirect_to @student + else + render "edit" + end + end + + def destroy + @student = Student.find params[:id] + + if @student.destroy + flash[:notice] = "Student Successfully Destroyed." + redirect_to students_path + else + render @student + end + end + + private + + def student_params + params.require(:student).permit(:name, :teacher_id) + end +end \ No newline at end of file diff --git a/app/controllers/teachers_controller.rb b/app/controllers/teachers_controller.rb new file mode 100644 index 0000000..f8971b9 --- /dev/null +++ b/app/controllers/teachers_controller.rb @@ -0,0 +1,9 @@ +class TeachersController < ApplicationController + def index + @teachers = Teacher.all + end + + def new + @student = Student.new + end +end \ No newline at end of file diff --git a/app/models/student.rb b/app/models/student.rb new file mode 100644 index 0000000..e333ce4 --- /dev/null +++ b/app/models/student.rb @@ -0,0 +1,5 @@ +class Student < ActiveRecord::Base + validates_presence_of :name + + belongs_to :teacher +end diff --git a/app/models/teacher.rb b/app/models/teacher.rb new file mode 100644 index 0000000..3cca1c5 --- /dev/null +++ b/app/models/teacher.rb @@ -0,0 +1,4 @@ +class Teacher < ActiveRecord::Base + validates_presence_of :name + has_many :students +end diff --git a/app/models/user.rb b/app/models/user.rb new file mode 100644 index 0000000..6d077a1 --- /dev/null +++ b/app/models/user.rb @@ -0,0 +1,3 @@ +class User < ActiveRecord::Base + include Clearance::User +end diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index a70d187..7b1c280 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -7,10 +7,33 @@ <%= csrf_meta_tags %> + +
+ +
+ <% if signed_in? %> + Welcome <%= current_user.email %> + <%= link_to 'Sign out', sign_out_path, :method => :delete %> + <% else %> + <%= link_to 'Sign in', sign_in_path %> +
+ <%= link_to 'Sign up', sign_up_path %> + <% end %> + +
+ <% flash.each do |key, value| %> +
<%= value %>
+ <% end %> +
+ +
+ + <%= render "shared/flash" %> <%= yield %>
+ diff --git a/app/views/pages/index.html.erb b/app/views/pages/index.html.erb new file mode 100644 index 0000000..1748081 --- /dev/null +++ b/app/views/pages/index.html.erb @@ -0,0 +1,4 @@ +

Welcome to the Readathon2 web app

+ + <%= link_to "Students", students_path %> + <%= link_to "Teachers", teachers_path %> \ No newline at end of file diff --git a/app/views/students/_form.html.erb b/app/views/students/_form.html.erb new file mode 100644 index 0000000..bdb77ef --- /dev/null +++ b/app/views/students/_form.html.erb @@ -0,0 +1,6 @@ +<%= simple_form_for @student do |f| %> + <%= f.input :name %> + <%= f.input :teacher_id, collection: Teacher.all %> + + <%= f.submit %> +<% end %> \ No newline at end of file diff --git a/app/views/students/edit.html.erb b/app/views/students/edit.html.erb new file mode 100644 index 0000000..577ec8b --- /dev/null +++ b/app/views/students/edit.html.erb @@ -0,0 +1 @@ +<%= render partial: "form" %> \ No newline at end of file diff --git a/app/views/students/index.html.erb b/app/views/students/index.html.erb new file mode 100644 index 0000000..f7db8d5 --- /dev/null +++ b/app/views/students/index.html.erb @@ -0,0 +1,9 @@ +

Students

+<%= link_to "Add Student", new_student_path %> +

+ +<% @students.each do |student| %> +
+ <%= link_to student.name, student %> +
+<% end %> \ No newline at end of file diff --git a/app/views/students/new.html.erb b/app/views/students/new.html.erb new file mode 100644 index 0000000..577ec8b --- /dev/null +++ b/app/views/students/new.html.erb @@ -0,0 +1 @@ +<%= render partial: "form" %> \ No newline at end of file diff --git a/app/views/students/show.html.erb b/app/views/students/show.html.erb new file mode 100644 index 0000000..dcd2255 --- /dev/null +++ b/app/views/students/show.html.erb @@ -0,0 +1,7 @@ +<%= link_to "Back to student list", students_path %> + +

<%= @student.name %>

+

<%= @student.teacher.name %>

+ +<%= link_to "Edit", edit_student_path %> +<%= link_to "Delete", @student, method: :delete, data:{confirm: "Are you sure?"} %> \ No newline at end of file diff --git a/app/views/teachers/index.html.erb b/app/views/teachers/index.html.erb new file mode 100644 index 0000000..2ee0221 --- /dev/null +++ b/app/views/teachers/index.html.erb @@ -0,0 +1,9 @@ +

Teachers

+<%= link_to "Add Teacher", new_teacher_path %> +

+ +<% @teachers.each do |teacher| %> +
+ <%= link_to teacher.name, teacher %> +
+<% end %> \ No newline at end of file diff --git a/config/environments/development.rb b/config/environments/development.rb index 4ca59fd..1c23e2e 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -26,4 +26,7 @@ # This option may cause significant delays in view rendering with a large # number of complex assets. config.assets.debug = true + + # for clearance generated urls + config.action_mailer.default_url_options = { :host => 'http://devbox-78291.usw1.nitrousbox.com/' } end diff --git a/config/environments/test.rb b/config/environments/test.rb index 39365ec..281de2b 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -33,4 +33,9 @@ # Print deprecation notices to the stderr. config.active_support.deprecation = :stderr + + # for clearance generated urls + config.action_mailer.default_url_options = { :host => 'http://devbox-78291.usw1.nitrousbox.com/' } + + config.action_controller.action_on_unpermitted_parameters = :raise end diff --git a/config/initializers/clearance.rb b/config/initializers/clearance.rb new file mode 100644 index 0000000..f0490ce --- /dev/null +++ b/config/initializers/clearance.rb @@ -0,0 +1,3 @@ +Clearance.configure do |config| + config.mailer_sender = 'reply@example.com' +end diff --git a/config/routes.rb b/config/routes.rb index c882e24..7695fd8 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,56 +1,5 @@ Readathon2::Application.routes.draw do - # The priority is based upon order of creation: first created -> highest priority. - # See how all your routes lay out with "rake routes". - - # You can have the root of your site routed with "root" - # root 'welcome#index' - - # Example of regular route: - # get 'products/:id' => 'catalog#view' - - # Example of named route that can be invoked with purchase_url(id: product.id) - # get 'products/:id/purchase' => 'catalog#purchase', as: :purchase - - # Example resource route (maps HTTP verbs to controller actions automatically): - # resources :products - - # Example resource route with options: - # resources :products do - # member do - # get 'short' - # post 'toggle' - # end - # - # collection do - # get 'sold' - # end - # end - - # Example resource route with sub-resources: - # resources :products do - # resources :comments, :sales - # resource :seller - # end - - # Example resource route with more complex sub-resources: - # resources :products do - # resources :comments - # resources :sales do - # get 'recent', on: :collection - # end - # end - - # Example resource route with concerns: - # concern :toggleable do - # post 'toggle' - # end - # resources :posts, concerns: :toggleable - # resources :photos, concerns: :toggleable - - # Example resource route within a namespace: - # namespace :admin do - # # Directs /admin/products/* to Admin::ProductsController - # # (app/controllers/admin/products_controller.rb) - # resources :products - # end -end + root 'pages#index' + resources :students + resources :teachers, only: [:index, :new, :show] +end \ No newline at end of file diff --git a/db/migrate/20140415012144_create_students.rb b/db/migrate/20140415012144_create_students.rb new file mode 100644 index 0000000..94f89a9 --- /dev/null +++ b/db/migrate/20140415012144_create_students.rb @@ -0,0 +1,9 @@ +class CreateStudents < ActiveRecord::Migration + def change + create_table :students do |t| + t.string :name + + t.timestamps + end + end +end diff --git a/db/migrate/20140429000650_create_users.rb b/db/migrate/20140429000650_create_users.rb new file mode 100644 index 0000000..5f93580 --- /dev/null +++ b/db/migrate/20140429000650_create_users.rb @@ -0,0 +1,18 @@ +class CreateUsers < ActiveRecord::Migration + def self.up + create_table :users do |t| + t.timestamps null: false + t.string :email, null: false + t.string :encrypted_password, limit: 128, null: false + t.string :confirmation_token, limit: 128 + t.string :remember_token, limit: 128, null: false + end + + add_index :users, :email + add_index :users, :remember_token + end + + def self.down + drop_table :users + end +end diff --git a/db/migrate/20140429010121_create_teachers.rb b/db/migrate/20140429010121_create_teachers.rb new file mode 100644 index 0000000..995c116 --- /dev/null +++ b/db/migrate/20140429010121_create_teachers.rb @@ -0,0 +1,9 @@ +class CreateTeachers < ActiveRecord::Migration + def change + create_table :teachers do |t| + t.string :name, null: false + + t.timestamps + end + end +end diff --git a/db/migrate/20140429011037_add_teacher_id_to_student.rb b/db/migrate/20140429011037_add_teacher_id_to_student.rb new file mode 100644 index 0000000..b2d4024 --- /dev/null +++ b/db/migrate/20140429011037_add_teacher_id_to_student.rb @@ -0,0 +1,5 @@ +class AddTeacherIdToStudent < ActiveRecord::Migration + def change + add_reference :students, :teacher, index: true + end +end diff --git a/db/schema.rb b/db/schema.rb index ea89ed5..c4ef1a5 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,9 +11,36 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 0) do +ActiveRecord::Schema.define(version: 20140429011037) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" + create_table "students", force: true do |t| + t.string "name" + t.datetime "created_at" + t.datetime "updated_at" + t.integer "teacher_id" + end + + add_index "students", ["teacher_id"], name: "index_students_on_teacher_id", using: :btree + + create_table "teachers", force: true do |t| + t.string "name", null: false + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "users", force: true do |t| + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "email", null: false + t.string "encrypted_password", limit: 128, null: false + t.string "confirmation_token", limit: 128 + t.string "remember_token", limit: 128, null: false + end + + add_index "users", ["email"], name: "index_users_on_email", using: :btree + add_index "users", ["remember_token"], name: "index_users_on_remember_token", using: :btree + end diff --git a/spec/factories/students.rb b/spec/factories/students.rb new file mode 100644 index 0000000..92e999b --- /dev/null +++ b/spec/factories/students.rb @@ -0,0 +1,7 @@ +# Read about factories at https://github.com/thoughtbot/factory_girl + +FactoryGirl.define do + factory :student do + name "Harry" + end +end diff --git a/spec/factories/teachers.rb b/spec/factories/teachers.rb new file mode 100644 index 0000000..a4ac612 --- /dev/null +++ b/spec/factories/teachers.rb @@ -0,0 +1,7 @@ +# Read about factories at https://github.com/thoughtbot/factory_girl + +FactoryGirl.define do + factory :teacher do + name "MyString" + end +end diff --git a/spec/factories/users.rb b/spec/factories/users.rb new file mode 100644 index 0000000..7509a97 --- /dev/null +++ b/spec/factories/users.rb @@ -0,0 +1,6 @@ +FactoryGirl.define do + factory :user do + email "joesmith@example.com" + password "password" + end +end diff --git a/spec/features/authentication.rb b/spec/features/authentication.rb new file mode 100644 index 0000000..789e0fe --- /dev/null +++ b/spec/features/authentication.rb @@ -0,0 +1,27 @@ +require 'spec_helper' + +feature 'Authentication' do + scenario 'Sign In' do + visit root_path + click_link "Sign in" + FactoryGirl.create :user, email: "joesmith@example.com", password: "password" + fill_in "Email", with: "joesmith@example.com" + fill_in "Password", with: "password" + click_button "Sign in" + expect(page).to have_content "Welcome joesmith@example.com" + click_link "Sign out" + expect(page).to have_content "Sign in" + end + + scenario 'Sign Up' do + visit root_path + click_link "Sign up" + + fill_in "Email", with: "joesmith2@example.com" + fill_in "Password", with: "password" + click_button "Sign up" + expect(page).to have_content "Welcome joesmith2@example.com" + click_link "Sign out" + expect(page).to have_content "Sign in" + end +end \ No newline at end of file diff --git a/spec/features/home_page_spec.rb b/spec/features/home_page_spec.rb index 3a90cbc..a504307 100644 --- a/spec/features/home_page_spec.rb +++ b/spec/features/home_page_spec.rb @@ -1,5 +1,10 @@ require 'spec_helper' feature 'Home page' do - scenario 'User views homepage' + scenario 'User views homepage' do + visit root_path + + expect(page).to have_content "Welcome" + expect(page).to have_title "Readathon2" + end end \ No newline at end of file diff --git a/spec/features/student_management_spec.rb b/spec/features/student_management_spec.rb index 7bcea6b..7722dba 100644 --- a/spec/features/student_management_spec.rb +++ b/spec/features/student_management_spec.rb @@ -1,7 +1,37 @@ require 'spec_helper' feature 'Student management' do - scenario 'A user can do the CRUD actions for students' + scenario 'A user can do the CRUD actions for students' do + FactoryGirl.create :teacher, name: "Mrs. Smith" + FactoryGirl.create :teacher, name: "Mrs. Jones" + + visit root_path + click_link "Students" + expect(page).to have_content "Students" + + click_link "Add Student" + fill_in "Name", with: "Bill" + select('Mrs. Smith', :from => 'Teacher') + click_button "Create Student" + expect(page).to have_content "Created" + + expect(page).to have_content "Bill" + click_link "Edit" + fill_in "Name", with: "Frank" + select('Mrs. Jones', :from => 'student_teacher_id') + click_button "Update Student" + expect(page).to have_content "Updated" + + expect(page).to have_content "Frank" + click_link "Delete" + expect(page).to have_content "Destroyed" + expect(page).to have_content "Students" + + end - scenario 'A user sees all students in the system' + scenario 'A user sees all students in the system'do + FactoryGirl.create_list :student, 4 + visit students_path + expect(page).to have_css ".student", count: 4 + end end \ No newline at end of file diff --git a/spec/features/teacher_management_spec.rb b/spec/features/teacher_management_spec.rb new file mode 100644 index 0000000..bf6d5c5 --- /dev/null +++ b/spec/features/teacher_management_spec.rb @@ -0,0 +1,33 @@ +require 'spec_helper' + +feature 'Teacher management' do + scenario 'A user can do the CRUD actions for teachers' do + # link to teacher management page + visit root_path + click_link "Teachers" + expect(page).to have_content "Teachers" + + # click create new teacher + click_link "Add Teacher" + fill_in "Name", with: "Hans" + click_button "Create Teacher" + expect(page).to have_content "Created" + expect(page).to have_content "Hans" + + click_link "Edit" + fill_in "Name", with: "Fritz" + click_button "Update Teacher" + expect(page).to have_content "Updated" + + expect(page).to have_content "Fritz" + click_link "Delete" + expect(page).to have_content "Destroyed" + expect(page).to have_content "Teachers" + end + + scenario 'A user sees all teachers in the system'do + FactoryGirl.create_list :teacher, 4 + visit teachers_path + expect(page).to have_css ".teacher", count: 4 + end +end \ No newline at end of file diff --git a/spec/models/student_spec.rb b/spec/models/student_spec.rb new file mode 100644 index 0000000..3b4176c --- /dev/null +++ b/spec/models/student_spec.rb @@ -0,0 +1,6 @@ +require 'spec_helper' + +describe Student do + it{should validate_presence_of(:name)} + it{should belong_to(:teacher)} +end diff --git a/spec/models/teacher_spec.rb b/spec/models/teacher_spec.rb new file mode 100644 index 0000000..7c2bdbb --- /dev/null +++ b/spec/models/teacher_spec.rb @@ -0,0 +1,5 @@ +require 'spec_helper' + +describe Teacher do + it{should validate_presence_of(:name)} +end