diff --git a/app/controllers/events_controller.rb b/app/controllers/events_controller.rb new file mode 100644 index 0000000..56287e2 --- /dev/null +++ b/app/controllers/events_controller.rb @@ -0,0 +1,65 @@ +class EventsController < ApplicationController + before_action :set_event, only: %i[ show edit update destroy ] + + # GET /events + def index + @events = Event.all + end + + # GET /events/1 + def show + end + + # GET /events/new + def new + kind = params[:profile] + kind = Profile.types.first unless Profile.types.include?(kind) + profile = current_member.profile(kind) + if(profile) + @event = Event.new profile: profile + else + redirect_to member_path(current_member), notice: "No such profile #{kind}." + end + end + + # GET /events/1/edit + def edit + end + + # POST /events + def create + @event = Event.new(event_params) + + if @event.save + redirect_to @event, notice: "Event was successfully created." + else + render :new, status: :unprocessable_entity + end + end + + # PATCH/PUT /events/1 + def update + if @event.update(event_params) + redirect_to @event, notice: "Event was successfully updated." + else + render :edit, status: :unprocessable_entity + end + end + + # DELETE /events/1 + def destroy + @event.destroy + redirect_to events_url, notice: "Event was successfully destroyed." + end + + private + # Use callbacks to share common setup or constraints between actions. + def set_event + @event = Event.find(params[:id]) + end + + # Only allow a list of trusted parameters through. + def event_params + params.require(:event).permit(:name, :text, :start_date, :end_date, :profile_id, :picture) + end +end diff --git a/app/helpers/events_helper.rb b/app/helpers/events_helper.rb new file mode 100644 index 0000000..8a9a878 --- /dev/null +++ b/app/helpers/events_helper.rb @@ -0,0 +1,2 @@ +module EventsHelper +end diff --git a/app/models/event.rb b/app/models/event.rb new file mode 100644 index 0000000..fbbfb24 --- /dev/null +++ b/app/models/event.rb @@ -0,0 +1,11 @@ +class Event < ApplicationRecord + belongs_to :profile + + validates :name , presence: true + validates :text , presence: true + validates :start_date , presence: true + validates :picture , presence: true + + mount_uploader :picture, PictureUploader + +end diff --git a/app/policies/edit_own_policy.rb b/app/policies/edit_own_policy.rb index 6a5afad..291e8ef 100644 --- a/app/policies/edit_own_policy.rb +++ b/app/policies/edit_own_policy.rb @@ -2,7 +2,11 @@ # which can be viewed by anyone class EditOwnPolicy < ApplicationPolicy def edit? - (member == record.member) or member.admin? + return true member.admin? + owner? + end + def owner? + member == record.member end alias :update? :edit? alias :destroy? :edit? diff --git a/app/policies/event_policy.rb b/app/policies/event_policy.rb new file mode 100644 index 0000000..d2b1309 --- /dev/null +++ b/app/policies/event_policy.rb @@ -0,0 +1,13 @@ +class EventPolicy < EditOwnPolicy + + def owner? + member == record.profile.member + end + + class Scope < Scope + # NOTE: Be explicit about which records you allow access to! + # def resolve + # scope.all + # end + end +end diff --git a/app/views/events/_form.html.haml b/app/views/events/_form.html.haml new file mode 100644 index 0000000..fd757b2 --- /dev/null +++ b/app/views/events/_form.html.haml @@ -0,0 +1,14 @@ += simple_form_for @event do |f| + = f.error_notification + + = f.input :name + = f.input :text + .grid.grid-cols-2.gap-10 + = f.input :start_date + = f.input :end_date + = f.input :profile_id , as: :hidden + = f.input :picture , as: :file + %button.mt-6.bg-cyan-200.mr-3.inline-block.rounded-lg.px-4.py-3.text-md.font-medium.border.border-gray-400 + = f.submit 'Save' + %button.ml-20.mr-3.inline-block.rounded-lg.px-4.py-3.text-md.font-medium.border.border-gray-400 + = link_to 'Back', @story diff --git a/app/views/events/edit.html.haml b/app/views/events/edit.html.haml new file mode 100644 index 0000000..4a3af83 --- /dev/null +++ b/app/views/events/edit.html.haml @@ -0,0 +1,6 @@ +.flex.justify-center + .column + .text-xl.m-4 + Editing event + + = render 'form' diff --git a/app/views/events/index.html.haml b/app/views/events/index.html.haml new file mode 100644 index 0000000..ae663e7 --- /dev/null +++ b/app/views/events/index.html.haml @@ -0,0 +1,31 @@ +%h1 Listing events + +%table + %thead + %tr + %th Name + %th Text + %th Start date + %th End date + %th Profile + %th Picture + %th + %th + %th + + %tbody + - @events.each do |event| + %tr + %td= event.name + %td= event.text + %td= event.start_date + %td= event.end_date + %td= event.profile + %td= event.picture + %td= link_to 'Show', event + %td= link_to 'Edit', edit_event_path(event) + %td= link_to 'Destroy', event, method: :delete, data: { confirm: 'Are you sure?' } + +%br + += link_to 'New Event', new_event_path diff --git a/app/views/events/new.html.haml b/app/views/events/new.html.haml new file mode 100644 index 0000000..04f3297 --- /dev/null +++ b/app/views/events/new.html.haml @@ -0,0 +1,6 @@ +.flex.justify-center + .column + .text-xl.m-4 + New event + + = render 'form' diff --git a/app/views/events/show.html.haml b/app/views/events/show.html.haml new file mode 100644 index 0000000..1625ec4 --- /dev/null +++ b/app/views/events/show.html.haml @@ -0,0 +1,24 @@ +%p#notice= notice + +%p + %b Name: + = @event.name +%p + %b Text: + = @event.text +%p + %b Start date: + = @event.start_date +%p + %b End date: + = @event.end_date +%p + %b Profile: + = @event.profile +%p + %b Picture: + = @event.picture + += link_to 'Edit', edit_event_path(@event) +\| += link_to 'Back', events_path diff --git a/app/views/members/_form.html.haml b/app/views/members/_form.html.haml index fe415a0..25c66c8 100644 --- a/app/views/members/_form.html.haml +++ b/app/views/members/_form.html.haml @@ -1,11 +1,5 @@ -= form_for @member do |f| - .flex.flex-col - - if @member.errors.any? - #error_explanation - %h2= "#{pluralize(@member.errors.count, "error")} prohibited this member from being saved:" - %ul - - @member.errors.full_messages.each do |message| - %li= message += simple_form_for @member do |f| + = f.error_notification .grid.grid-cols-2.m-20.gap-10 .field diff --git a/app/views/members/show.html.haml b/app/views/members/show.html.haml index d53e98b..899cbbd 100644 --- a/app/views/members/show.html.haml +++ b/app/views/members/show.html.haml @@ -13,7 +13,7 @@ .grid.grid-cols-2.mx-20 .first - Profile.types.each do |kind| - .grid.grid-cols-2 + .grid.grid-cols-3 - if profile = @member.profile(kind) %div =profile.Kind @@ -23,12 +23,17 @@ %button.bg-cyan-200.mr-3.inline-block.rounded-lg.px-4.py-3.text-md.font-medium.border.border-gray-400 Edit =profile.Kind + + = link_to new_event_path(profile: profile.kind) do + %button.bg-cyan-200.mr-3.inline-block.rounded-lg.px-4.py-3.text-md.font-medium.border.border-gray-400 + New #{profile.Kind} Event -else %div Create new #{kind.capitalize} profile as = link_to new_profile_path(kind: kind) do %button.bg-cyan-200.mr-3.inline-block.rounded-lg.px-4.py-3.text-md.font-medium.border.border-gray-400 New = kind.capitalize + %div Create profile first, then events .grid.grid-cols-6.gap-4.mt-10.mx-10 diff --git a/config/routes.rb b/config/routes.rb index e47ac11..fb962db 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,4 +1,5 @@ Rails.application.routes.draw do + resources :events resources :profiles resources :entities diff --git a/db/migrate/20230116120518_create_events.rb b/db/migrate/20230116120518_create_events.rb new file mode 100644 index 0000000..87160f4 --- /dev/null +++ b/db/migrate/20230116120518_create_events.rb @@ -0,0 +1,14 @@ +class CreateEvents < ActiveRecord::Migration[7.0] + def change + create_table :events do |t| + t.string :name , null: false + t.text :text , null: false + t.date :start_date , null: false + t.date :end_date + t.references :profile, null: false, foreign_key: true + t.string :picture , null: false + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 6cecaf6..1730331 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_15_120517) do +ActiveRecord::Schema[7.0].define(version: 2023_01_16_120518) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -24,6 +24,18 @@ ActiveRecord::Schema[7.0].define(version: 2023_01_15_120517) do t.index ["member_id"], name: "index_entities_on_member_id" end + create_table "events", force: :cascade do |t| + t.string "name", null: false + t.text "text", null: false + t.date "start_date", null: false + t.date "end_date" + t.bigint "profile_id", null: false + t.string "picture", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["profile_id"], name: "index_events_on_profile_id" + end + create_table "friendly_id_slugs", force: :cascade do |t| t.string "slug", null: false t.integer "sluggable_id", null: false @@ -295,6 +307,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_01_15_120517) do end add_foreign_key "entities", "members" + add_foreign_key "events", "profiles" add_foreign_key "profiles", "members" add_foreign_key "thredded_messageboard_users", "thredded_messageboards", on_delete: :cascade add_foreign_key "thredded_messageboard_users", "thredded_user_details", on_delete: :cascade diff --git a/test/fixtures/events.yml b/test/fixtures/events.yml new file mode 100644 index 0000000..22e5b86 --- /dev/null +++ b/test/fixtures/events.yml @@ -0,0 +1,17 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + name: MyString + text: MyText + start_date: 2023-01-16 + end_date: 2023-01-16 + profile: one + picture: MyString + +two: + name: MyString + text: MyText + start_date: 2023-01-16 + end_date: 2023-01-16 + profile: two + picture: MyString diff --git a/test/models/event_test.rb b/test/models/event_test.rb new file mode 100644 index 0000000..c8465c1 --- /dev/null +++ b/test/models/event_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class EventTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/policies/event_policy_test.rb b/test/policies/event_policy_test.rb new file mode 100644 index 0000000..06b0cc3 --- /dev/null +++ b/test/policies/event_policy_test.rb @@ -0,0 +1,18 @@ +require 'test_helper' + +class EventPolicyTest < ActiveSupport::TestCase + def test_scope + end + + def test_show + end + + def test_create + end + + def test_update + end + + def test_destroy + end +end diff --git a/test/system/events_test.rb b/test/system/events_test.rb new file mode 100644 index 0000000..d32c4bb --- /dev/null +++ b/test/system/events_test.rb @@ -0,0 +1,51 @@ +require "application_system_test_case" + +class EventsTest < ApplicationSystemTestCase + setup do + @event = events(:one) + end + + test "visiting the index" do + visit events_url + assert_selector "h1", text: "Events" + end + + test "should create event" do + visit events_url + click_on "New event" + + fill_in "End date", with: @event.end_date + fill_in "Name", with: @event.name + fill_in "Picture", with: @event.picture + fill_in "Profile", with: @event.profile_id + fill_in "Start date", with: @event.start_date + fill_in "Text", with: @event.text + click_on "Create Event" + + assert_text "Event was successfully created" + click_on "Back" + end + + test "should update Event" do + visit event_url(@event) + click_on "Edit this event", match: :first + + fill_in "End date", with: @event.end_date + fill_in "Name", with: @event.name + fill_in "Picture", with: @event.picture + fill_in "Profile", with: @event.profile_id + fill_in "Start date", with: @event.start_date + fill_in "Text", with: @event.text + click_on "Update Event" + + assert_text "Event was successfully updated" + click_on "Back" + end + + test "should destroy Event" do + visit event_url(@event) + click_on "Destroy this event", match: :first + + assert_text "Event was successfully destroyed" + end +end