From 750bd76a7e0d4b612f32e9aa08e5d89c0d85a531 Mon Sep 17 00:00:00 2001 From: Torsten Date: Sun, 15 Jan 2023 14:52:40 +0200 Subject: [PATCH] adding teacher profiles --- app/controllers/teachers_controller.rb | 59 ++++++++++++++++++++ app/helpers/teachers_helper.rb | 2 + app/models/entity.rb | 4 +- app/models/member.rb | 7 +-- app/models/teacher.rb | 10 ++++ app/views/devise/registrations/new.html.haml | 2 +- app/views/members/index.html.haml | 37 +++++------- app/views/members/show.html.haml | 9 +++ app/views/teachers/_form.html.haml | 13 +++++ app/views/teachers/edit.html.haml | 4 ++ app/views/teachers/index.html.haml | 16 ++++++ app/views/teachers/new.html.haml | 4 ++ app/views/teachers/show.html.haml | 10 ++++ config/initializers/simple_form.rb | 2 +- config/routes.rb | 1 + db/migrate/20230115120517_create_teachers.rb | 12 ++++ db/schema.rb | 13 ++++- test/controllers/teachers_controller_test.rb | 48 ++++++++++++++++ test/fixtures/teachers.yml | 13 +++++ test/models/teacher_test.rb | 7 +++ test/system/teachers_test.rb | 47 ++++++++++++++++ 21 files changed, 288 insertions(+), 32 deletions(-) create mode 100644 app/controllers/teachers_controller.rb create mode 100644 app/helpers/teachers_helper.rb create mode 100644 app/models/teacher.rb create mode 100644 app/views/teachers/_form.html.haml create mode 100644 app/views/teachers/edit.html.haml create mode 100644 app/views/teachers/index.html.haml create mode 100644 app/views/teachers/new.html.haml create mode 100644 app/views/teachers/show.html.haml create mode 100644 db/migrate/20230115120517_create_teachers.rb create mode 100644 test/controllers/teachers_controller_test.rb create mode 100644 test/fixtures/teachers.yml create mode 100644 test/models/teacher_test.rb create mode 100644 test/system/teachers_test.rb diff --git a/app/controllers/teachers_controller.rb b/app/controllers/teachers_controller.rb new file mode 100644 index 0000000..6db265e --- /dev/null +++ b/app/controllers/teachers_controller.rb @@ -0,0 +1,59 @@ +class TeachersController < ApplicationController + before_action :set_teacher, only: %i[ show edit update destroy ] + + # GET /teachers + def index + @teachers = Teacher.all + end + + # GET /teachers/1 + def show + end + + # GET /teachers/new + def new + @teacher = Teacher.new + end + + # GET /teachers/1/edit + def edit + end + + # POST /teachers + def create + @teacher = Teacher.new(teacher_params) + @teacher.member = current_member + + if @teacher.save + redirect_to @teacher, notice: "Successfully created Teacher profile" + else + render :new, status: :unprocessable_entity + end + end + + # PATCH/PUT /teachers/1 + def update + if @teacher.update(teacher_params) + redirect_to @teacher, notice: "Teacher Profile was updated." + else + render :edit, status: :unprocessable_entity + end + end + + # DELETE /teachers/1 + def destroy + @teacher.destroy + redirect_to teachers_url, notice: "Teacher was successfully destroyed." + end + + private + # Use callbacks to share common setup or constraints between actions. + def set_teacher + @teacher = Teacher.find(params[:id]) + end + + # Only allow a list of trusted parameters through. + def teacher_params + params.require(:teacher).permit(:name, :bio, :picture) + end +end diff --git a/app/helpers/teachers_helper.rb b/app/helpers/teachers_helper.rb new file mode 100644 index 0000000..1015c8c --- /dev/null +++ b/app/helpers/teachers_helper.rb @@ -0,0 +1,2 @@ +module TeachersHelper +end diff --git a/app/models/entity.rb b/app/models/entity.rb index 6d5cea5..4a2aa0c 100644 --- a/app/models/entity.rb +++ b/app/models/entity.rb @@ -20,8 +20,8 @@ class Entity < ApplicationRecord end def self.response(path = "") - host = Rails.credentials.weather_dev - host = Rails.credentials.weather_pro if Rails.env.production? + host = Rails.application.credentials.weather_dev + host = Rails.application.credentials.weather_pro if Rails.env.production? token = Rails.application.credentials.weather_token begin all = RestClient.get( "#{host}:8123/api/states#{path}" , diff --git a/app/models/member.rb b/app/models/member.rb index bf49c4b..a7a27a4 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -7,11 +7,10 @@ class Member < ApplicationRecord mount_uploader :picture, PictureUploader has_many :entities + has_one :teacher - def admin - true - end def admin? - true + email == "torsten@villataika.fi" end + alias :admin :admin? end diff --git a/app/models/teacher.rb b/app/models/teacher.rb new file mode 100644 index 0000000..b3998bb --- /dev/null +++ b/app/models/teacher.rb @@ -0,0 +1,10 @@ +class Teacher < ApplicationRecord + belongs_to :member + + validates :name , presence: true + validates :bio , presence: true + validates :picture , presence: true + + mount_uploader :picture, PictureUploader + +end diff --git a/app/views/devise/registrations/new.html.haml b/app/views/devise/registrations/new.html.haml index 36fe783..075b11d 100644 --- a/app/views/devise/registrations/new.html.haml +++ b/app/views/devise/registrations/new.html.haml @@ -9,7 +9,7 @@ = f.label :name, class: "block font-bold mb-2 text-gray-700 text-sm" = f.text_field :name, autocomplete: "name", - placeholder: "Pekka Juustonen", + placeholder: "Joona Virtanen", class: "appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none shadow focus:shadow-outline" .mb-4 = f.label :email, class: "block font-bold mb-2 text-gray-700 text-sm" diff --git a/app/views/members/index.html.haml b/app/views/members/index.html.haml index ea556b4..c1e9f7f 100644 --- a/app/views/members/index.html.haml +++ b/app/views/members/index.html.haml @@ -1,25 +1,16 @@ += paginate @members .flex.justify-center - %h1 Listing members - - %table - %thead - %tr - %th Name - %th Public - %th - %th - %th - - %tbody - - @members.each do |member| - %tr - %td= member.name - %td= member.public - %td= link_to 'Show', member - %td= link_to 'Edit', edit_member_path(member) - %td= link_to 'Destroy', member, method: :delete, data: { confirm: 'Are you sure?' } - - %br - - = link_to 'New Member', new_member_path + .grid.grid-cols-4 + - @members.each do |member| + .fex.flex-col.overflow-hidden.rounded-lg.border.border-gray-100.shadow-sm.m-10 + =link_to member do + = image_for( member , class: "h-60 w-full object-cover") + %h3.pt-5.text-2xl.bg-gray-100.text-black.font-bold.text-center + = member.name + .p-2.text-xs.bg-gray-50.text-black.font-bold.text-center + = stayed member + %div.h-full + .p-5.text-center + .m-2.text-sm.leading-relaxed.line-clamp-3{ prose_classes } + = shorten markdown(member.bio) diff --git a/app/views/members/show.html.haml b/app/views/members/show.html.haml index 0d1cd28..2c97829 100644 --- a/app/views/members/show.html.haml +++ b/app/views/members/show.html.haml @@ -23,6 +23,15 @@ = link_to edit_member_path(@member) do %button.bg-cyan-200.mr-3.inline-block.rounded-lg.px-4.py-3.text-md.font-medium.border.border-gray-400 Edit + - if @member.teacher + = link_to edit_teacher_path(@member.teacher) do + %button.bg-cyan-200.mr-3.inline-block.rounded-lg.px-4.py-3.text-md.font-medium.border.border-gray-400 + Edit teacher profile + -else + = link_to new_teacher_path do + %button.bg-cyan-200.mr-3.inline-block.rounded-lg.px-4.py-3.text-md.font-medium.border.border-gray-400 + Create teacher profile + .grid.grid-cols-3.gap-4 -@member.entities.each do |entity| %div= entity.type diff --git a/app/views/teachers/_form.html.haml b/app/views/teachers/_form.html.haml new file mode 100644 index 0000000..c445eb3 --- /dev/null +++ b/app/views/teachers/_form.html.haml @@ -0,0 +1,13 @@ += simple_form_for @teacher do |f| + = f.error_notification + + = f.input :name + = f.input :bio + = f.input :picture , as: :file , label: (@teacher.picture.blank? ? "Add picture" : "Change picture (optional)") + + .flex.justify-between.mt-4 + %button.bg-cyan-200{class: button_classes} + = f.submit 'Save' + + %button.bg-cyan-200{class: button_classes} + = link_to 'Cancel', teachers_path diff --git a/app/views/teachers/edit.html.haml b/app/views/teachers/edit.html.haml new file mode 100644 index 0000000..fb59745 --- /dev/null +++ b/app/views/teachers/edit.html.haml @@ -0,0 +1,4 @@ +.flex.justify-center + .column + .text-xl.m-4 Edit your teacher profile + = render 'form' diff --git a/app/views/teachers/index.html.haml b/app/views/teachers/index.html.haml new file mode 100644 index 0000000..f6d1c9a --- /dev/null +++ b/app/views/teachers/index.html.haml @@ -0,0 +1,16 @@ += paginate @teachers +.flex.justify-center + + .grid.grid-cols-4 + - @teachers.each do |teacher| + .fex.flex-col.overflow-hidden.rounded-lg.border.border-gray-100.shadow-sm.m-10 + =link_to teacher do + = image_for( teacher , class: "h-60 w-full object-cover") + %h3.pt-5.text-2xl.bg-gray-100.text-black.font-bold.text-center + = teacher.name + .p-2.text-xs.bg-gray-50.text-black.font-bold.text-center + = stayed teacher + %div.h-full + .p-5.text-center + .m-2.text-sm.leading-relaxed.line-clamp-3{ prose_classes } + = shorten markdown(teacher.bio) diff --git a/app/views/teachers/new.html.haml b/app/views/teachers/new.html.haml new file mode 100644 index 0000000..660f25c --- /dev/null +++ b/app/views/teachers/new.html.haml @@ -0,0 +1,4 @@ +.flex.justify-center + .column + .text-xl.m-4 Create your teacher profile + = render 'form' diff --git a/app/views/teachers/show.html.haml b/app/views/teachers/show.html.haml new file mode 100644 index 0000000..16c8410 --- /dev/null +++ b/app/views/teachers/show.html.haml @@ -0,0 +1,10 @@ +.px-4.py-16.mx-auto.sm:max-w-xl.md:max-w-full.lg:max-w-screen-xl.md:px-24.lg:px-8.lg:py-20 + .flex.flex-col.max-w-screen-lg.overflow-hidden.bg-white.border.rounded.shadow-sm.lg:flex-row.sm:mx-auto + .relative{:class => "lg:w-1/2"} + -if @teacher.picture_url + = image_tag @teacher.picture_url, class: "object-cover w-full lg:absolute h-80 lg:h-full" + .flex.flex-col.justify-center.p-8.lg:p-16.lg:pl-10{:class => "lg:w-1/2"} + %h5.mb-3.text-3xl.font-extrabold.leading-none.sm:text-4xl + = @teacher.name + .mb-8.text-gray-800 + .prose= markdown(@teacher.bio) diff --git a/config/initializers/simple_form.rb b/config/initializers/simple_form.rb index 9293903..4131d36 100644 --- a/config/initializers/simple_form.rb +++ b/config/initializers/simple_form.rb @@ -14,7 +14,7 @@ SimpleForm.setup do |config| # stack. The options given below are used to wrap the # whole input. - config.wrappers :default, tag: 'div', class: '', error_class: '', valid_class: '' do |b| + config.wrappers :default, tag: 'div', class: 'mt-4', error_class: '', valid_class: '' do |b| b.use :html5 b.use :placeholder b.optional :maxlength diff --git a/config/routes.rb b/config/routes.rb index 8e96c71..4afda60 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,4 +1,5 @@ Rails.application.routes.draw do + resources :teachers resources :entities devise_for :members diff --git a/db/migrate/20230115120517_create_teachers.rb b/db/migrate/20230115120517_create_teachers.rb new file mode 100644 index 0000000..5693fcc --- /dev/null +++ b/db/migrate/20230115120517_create_teachers.rb @@ -0,0 +1,12 @@ +class CreateTeachers < ActiveRecord::Migration[7.0] + def change + create_table :teachers do |t| + t.string :name , null: false + t.text :bio , null: false + t.string :picture , null: false + t.references :member, null: false, foreign_key: true + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index b21f953..5e3903f 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2023_01_13_170732) do +ActiveRecord::Schema[7.0].define(version: 2023_01_15_120517) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -56,6 +56,16 @@ ActiveRecord::Schema[7.0].define(version: 2023_01_13_170732) do t.index ["reset_password_token"], name: "index_members_on_reset_password_token", unique: true end + create_table "teachers", force: :cascade do |t| + t.string "name", null: false + t.text "bio", null: false + t.string "picture", null: false + t.bigint "member_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["member_id"], name: "index_teachers_on_member_id" + end + create_table "thredded_categories", force: :cascade do |t| t.bigint "messageboard_id", null: false t.text "name", null: false @@ -288,6 +298,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_01_13_170732) do end add_foreign_key "entities", "members" + add_foreign_key "teachers", "members" add_foreign_key "thredded_messageboard_users", "thredded_messageboards", on_delete: :cascade add_foreign_key "thredded_messageboard_users", "thredded_user_details", on_delete: :cascade add_foreign_key "thredded_user_post_notifications", "members", column: "user_id", on_delete: :cascade diff --git a/test/controllers/teachers_controller_test.rb b/test/controllers/teachers_controller_test.rb new file mode 100644 index 0000000..62a971c --- /dev/null +++ b/test/controllers/teachers_controller_test.rb @@ -0,0 +1,48 @@ +require "test_helper" + +class TeachersControllerTest < ActionDispatch::IntegrationTest + setup do + @teacher = teachers(:one) + end + + test "should get index" do + get teachers_url + assert_response :success + end + + test "should get new" do + get new_teacher_url + assert_response :success + end + + test "should create teacher" do + assert_difference("Teacher.count") do + post teachers_url, params: { teacher: { bio: @teacher.bio, member_id: @teacher.member_id, name: @teacher.name, picture: @teacher.picture } } + end + + assert_redirected_to teacher_url(Teacher.last) + end + + test "should show teacher" do + get teacher_url(@teacher) + assert_response :success + end + + test "should get edit" do + get edit_teacher_url(@teacher) + assert_response :success + end + + test "should update teacher" do + patch teacher_url(@teacher), params: { teacher: { bio: @teacher.bio, member_id: @teacher.member_id, name: @teacher.name, picture: @teacher.picture } } + assert_redirected_to teacher_url(@teacher) + end + + test "should destroy teacher" do + assert_difference("Teacher.count", -1) do + delete teacher_url(@teacher) + end + + assert_redirected_to teachers_url + end +end diff --git a/test/fixtures/teachers.yml b/test/fixtures/teachers.yml new file mode 100644 index 0000000..7e4f2e9 --- /dev/null +++ b/test/fixtures/teachers.yml @@ -0,0 +1,13 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + name: MyString + bio: MyString + picture: MyString + member: one + +two: + name: MyString + bio: MyString + picture: MyString + member: two diff --git a/test/models/teacher_test.rb b/test/models/teacher_test.rb new file mode 100644 index 0000000..55fa9e9 --- /dev/null +++ b/test/models/teacher_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class TeacherTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/system/teachers_test.rb b/test/system/teachers_test.rb new file mode 100644 index 0000000..55bffc7 --- /dev/null +++ b/test/system/teachers_test.rb @@ -0,0 +1,47 @@ +require "application_system_test_case" + +class TeachersTest < ApplicationSystemTestCase + setup do + @teacher = teachers(:one) + end + + test "visiting the index" do + visit teachers_url + assert_selector "h1", text: "Teachers" + end + + test "should create teacher" do + visit teachers_url + click_on "New teacher" + + fill_in "Bio", with: @teacher.bio + fill_in "Member", with: @teacher.member_id + fill_in "Name", with: @teacher.name + fill_in "Picture", with: @teacher.picture + click_on "Create Teacher" + + assert_text "Teacher was successfully created" + click_on "Back" + end + + test "should update Teacher" do + visit teacher_url(@teacher) + click_on "Edit this teacher", match: :first + + fill_in "Bio", with: @teacher.bio + fill_in "Member", with: @teacher.member_id + fill_in "Name", with: @teacher.name + fill_in "Picture", with: @teacher.picture + click_on "Update Teacher" + + assert_text "Teacher was successfully updated" + click_on "Back" + end + + test "should destroy Teacher" do + visit teacher_url(@teacher) + click_on "Destroy this teacher", match: :first + + assert_text "Teacher was successfully destroyed" + end +end