From e7b24d120136366f5d47d2457e9f1d477eb6256d Mon Sep 17 00:00:00 2001 From: Torsten Date: Wed, 25 Jan 2023 22:15:54 +0200 Subject: [PATCH] first gallery version --- app/controllers/pictures_controller.rb | 55 ++++++++++++++++++++ app/controllers/stories_controller.rb | 4 +- app/helpers/members_helper.rb | 7 ++- app/helpers/pictures_helper.rb | 2 + app/models/member.rb | 4 +- app/models/picture.rb | 9 ++++ app/policies/picture_policy.rb | 3 ++ app/policies/story_policy.rb | 6 --- app/views/pictures/_form.haml | 18 +++++++ app/views/pictures/_picture.haml | 11 ++++ app/views/pictures/edit.html.haml | 7 +++ app/views/pictures/index.html.haml | 17 ++++++ app/views/pictures/new.html.haml | 7 +++ app/views/pictures/show.html.haml | 11 ++++ config/routes.rb | 1 + db/migrate/20230125172223_create_pictures.rb | 12 +++++ db/schema.rb | 13 ++++- test/controllers/pictures_controller_test.rb | 48 +++++++++++++++++ test/fixtures/pictures.yml | 11 ++++ test/models/picture_test.rb | 7 +++ test/policies/picture_policy_test.rb | 18 +++++++ test/system/pictures_test.rb | 45 ++++++++++++++++ 22 files changed, 304 insertions(+), 12 deletions(-) create mode 100644 app/controllers/pictures_controller.rb create mode 100644 app/helpers/pictures_helper.rb create mode 100644 app/models/picture.rb create mode 100644 app/policies/picture_policy.rb create mode 100644 app/views/pictures/_form.haml create mode 100644 app/views/pictures/_picture.haml create mode 100644 app/views/pictures/edit.html.haml create mode 100644 app/views/pictures/index.html.haml create mode 100644 app/views/pictures/new.html.haml create mode 100644 app/views/pictures/show.html.haml create mode 100644 db/migrate/20230125172223_create_pictures.rb create mode 100644 test/controllers/pictures_controller_test.rb create mode 100644 test/fixtures/pictures.yml create mode 100644 test/models/picture_test.rb create mode 100644 test/policies/picture_policy_test.rb create mode 100644 test/system/pictures_test.rb diff --git a/app/controllers/pictures_controller.rb b/app/controllers/pictures_controller.rb new file mode 100644 index 0000000..2900544 --- /dev/null +++ b/app/controllers/pictures_controller.rb @@ -0,0 +1,55 @@ +class PicturesController < ApplicationController + before_action :set_picture, only: %i[ show edit update destroy ] + + def index + @q = Picture.ransack(params[:q]) + @q.sorts = 'created_at desc' if @q.sorts.empty? + @pictures = @q.result(distinct: true).page( params[:page]) + end + + def show + end + + def new + @picture = Picture.new + end + + def edit + authorize @picture + end + + def create + @picture = Picture.new(picture_params) + @picture.member = current_member + + if @picture.save + redirect_to @picture, notice: "Picture was successfully created." + else + render :new, status: :unprocessable_entity + end + end + + def update + authorize @picture + if @picture.update(picture_params) + redirect_to @picture, notice: "Picture was successfully updated." + else + render :edit, status: :unprocessable_entity + end + end + + def destroy + authorize @picture + @picture.destroy + redirect_to pictures_url, notice: "Picture was successfully destroyed." + end + + private + def set_picture + @picture = Picture.find(params[:id]) + end + + def picture_params + params.require(:picture).permit(:picture,:picture_cache ,:text, :member_id) + end +end diff --git a/app/controllers/stories_controller.rb b/app/controllers/stories_controller.rb index 91b684d..61d8280 100644 --- a/app/controllers/stories_controller.rb +++ b/app/controllers/stories_controller.rb @@ -45,13 +45,11 @@ class StoriesController < ApplicationController end private - # Use callbacks to share common setup or constraints between actions. def set_story @story = Story.find(params[:id]) end - # Only allow a list of trusted parameters through. def story_params - params.require(:story).permit(:picture, :header, :text, :happened) + params.require(:story).permit(:picture,:picture_cache, :header, :text, :happened) end end diff --git a/app/helpers/members_helper.rb b/app/helpers/members_helper.rb index 338767e..96b1aaf 100644 --- a/app/helpers/members_helper.rb +++ b/app/helpers/members_helper.rb @@ -6,7 +6,12 @@ module MembersHelper else image = someone.picture.url end - image_tag(image , alt: someone.name , class: classes ) + if someone.respond_to? :name + alt = someone.name + else + alt = "" + end + image_tag(image , alt: alt , class: classes ) end def stayed(member) diff --git a/app/helpers/pictures_helper.rb b/app/helpers/pictures_helper.rb new file mode 100644 index 0000000..f1a9d9c --- /dev/null +++ b/app/helpers/pictures_helper.rb @@ -0,0 +1,2 @@ +module PicturesHelper +end diff --git a/app/models/member.rb b/app/models/member.rb index 3b19e35..6d7546c 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -6,7 +6,9 @@ class Member < ApplicationRecord mount_uploader :picture, PictureUploader has_many :stories - + has_many :stories + has_many :pictures + validates :bio, length: { maximum: 1000 } validates :name , length: { minimum: 3 } diff --git a/app/models/picture.rb b/app/models/picture.rb new file mode 100644 index 0000000..098dc61 --- /dev/null +++ b/app/models/picture.rb @@ -0,0 +1,9 @@ +class Picture < ApplicationRecord + belongs_to :member + + mount_uploader :picture, PictureUploader + + validates :text, length: { maximum: 80 } + + +end diff --git a/app/policies/picture_policy.rb b/app/policies/picture_policy.rb new file mode 100644 index 0000000..efc68d0 --- /dev/null +++ b/app/policies/picture_policy.rb @@ -0,0 +1,3 @@ +class PicturePolicy < EditOwnPolicy + +end diff --git a/app/policies/story_policy.rb b/app/policies/story_policy.rb index fb142fb..2b2b0d3 100644 --- a/app/policies/story_policy.rb +++ b/app/policies/story_policy.rb @@ -1,9 +1,3 @@ class StoryPolicy < EditOwnPolicy - def edit? - (member == record.member) or member.admin? - end - alias :update? :edit? - alias :destroy? :edit? - end diff --git a/app/views/pictures/_form.haml b/app/views/pictures/_form.haml new file mode 100644 index 0000000..731df87 --- /dev/null +++ b/app/views/pictures/_form.haml @@ -0,0 +1,18 @@ +%div + Pictures may have a small text, that will be diplayed on top of the + picure. + = simple_form_for @picture do |f| + = f.error_notification + .flex.h-16.mt-2 + = image_tag(@picture.picture_url , class: "align-middle mr-2") if @picture.picture? + = f.input :picture , as: :file , input_html: {wrapper_class: "w-full"}, + label: (@picture.picture.blank? ? "Add picture" : "Change picture") + = f.hidden_field :picture_cache + = f.input :text , as: :text , input_html: { rows: 2 } + = f.input :happened , wrapper_class: "flex mt-4 align-center" + .flex.justify-between.mt-6 + %button.bg-cyan-200.rounded-lg.px-4.py-3.text-md.font-medium.border.border-gray-400 + = f.submit 'Save' + = link_to member_path(current_member) do + %button.ml-20.rounded-lg.px-4.py-3.text-md.font-medium.border.border-gray-400 + Back diff --git a/app/views/pictures/_picture.haml b/app/views/pictures/_picture.haml new file mode 100644 index 0000000..5ea317a --- /dev/null +++ b/app/views/pictures/_picture.haml @@ -0,0 +1,11 @@ +.group.h-96.items-end.relative.overflow-hidden + = image_for( picture , "inset-0 h-full w-full object-fit hover:scale-110 ease-in duration-700") + -unless picture.text.blank? + .absolute.mb-10.p-2.tracking-widest.text-left.text-black{class: "max-w-2/3"} + %div.transition-colors.group-hover:bg-black.group-hover:text-white.text-left.bg-gray-100 + .m-1.p-1.text-xs + = picture.text + = picture.text + %div.bg-cyan-200 + %div Torsten + %div some date diff --git a/app/views/pictures/edit.html.haml b/app/views/pictures/edit.html.haml new file mode 100644 index 0000000..f661396 --- /dev/null +++ b/app/views/pictures/edit.html.haml @@ -0,0 +1,7 @@ +%script{:src => "https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"} +%script{:src => "https://cdn.jsdelivr.net/npm/marked/marked.min.js"} +.flex.justify-center + .column{class: "w-10/12 md:w-8/12 lg:w-7/12 xl:w-6/12"} + .text-2xl.font-bold.my-4 + Edit Picture + = render 'form' diff --git a/app/views/pictures/index.html.haml b/app/views/pictures/index.html.haml new file mode 100644 index 0000000..5543e2e --- /dev/null +++ b/app/views/pictures/index.html.haml @@ -0,0 +1,17 @@ += paginate @pictures + +.flex.justify-end + = sort_link(@q, :happened ,class: 'flex flex-nowrap text-md') + .border-r-4.mx-4 + = sort_link(@q, :created_at , class: 'flex flex-nowrap text-md') + +.grid.grid-cols-1.md:grid-cols-2.lg:grid-cols-3.gap-8.md:gap-12.lg:gap-16 + - @pictures.each do |picture| + = render picture , picture: picture + +%br + +.flex.ml-20 + = link_to new_picture_path do + %button.bg-cyan-200.mr-3.inline-block.rounded-lg.px-4.py-3.text-md.font-medium.border.border-gray-400 + New Picture diff --git a/app/views/pictures/new.html.haml b/app/views/pictures/new.html.haml new file mode 100644 index 0000000..57eea68 --- /dev/null +++ b/app/views/pictures/new.html.haml @@ -0,0 +1,7 @@ +%script{:src => "https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"} +%script{:src => "https://cdn.jsdelivr.net/npm/marked/marked.min.js"} +.flex.justify-center + .column{class: "w-10/12 md:w-8/12 lg:w-7/12 xl:w-6/12"} + .text-2xl.font-bold.my-4 + New Picture + = render 'form' diff --git a/app/views/pictures/show.html.haml b/app/views/pictures/show.html.haml new file mode 100644 index 0000000..d25f3fa --- /dev/null +++ b/app/views/pictures/show.html.haml @@ -0,0 +1,11 @@ +.grid.grid-cols-1.md:grid-cols-2.lg:grid-cols-3.gap-8.md:gap-12.lg:gap-16 + %div + = render @picture , picture: @picture + +.mx-20.flex.justify-between + = link_to edit_picture_path(@picture) do + %button.mt-6.bg-cyan-200.mr-3.inline-block.rounded-lg.px-4.py-3.text-md.font-medium.border.border-gray-400 + Edit + = link_to pictures_path do + %button.mt-6.mr-3.inline-block.rounded-lg.px-4.py-3.text-md.font-medium.border.border-gray-400 + Back diff --git a/config/routes.rb b/config/routes.rb index a2be4e2..ef2a676 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,4 +1,5 @@ Rails.application.routes.draw do + resources :pictures resources :stories devise_for :members ,controllers: { registrations: 'registrations' } diff --git a/db/migrate/20230125172223_create_pictures.rb b/db/migrate/20230125172223_create_pictures.rb new file mode 100644 index 0000000..527448a --- /dev/null +++ b/db/migrate/20230125172223_create_pictures.rb @@ -0,0 +1,12 @@ +class CreatePictures < ActiveRecord::Migration[7.0] + def change + create_table :pictures do |t| + t.string :picture + t.string :text + t.date :happened + t.references :member, null: false, foreign_key: true + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index a62042e..3265ca5 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_12_123705) do +ActiveRecord::Schema[7.0].define(version: 2023_01_25_172223) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -48,6 +48,16 @@ ActiveRecord::Schema[7.0].define(version: 2023_01_12_123705) do t.index ["reset_password_token"], name: "index_members_on_reset_password_token", unique: true end + create_table "pictures", force: :cascade do |t| + t.string "picture" + t.string "text" + t.date "happened" + t.bigint "member_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["member_id"], name: "index_pictures_on_member_id" + end + create_table "stories", force: :cascade do |t| t.bigint "member_id" t.string "picture" @@ -290,6 +300,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_01_12_123705) do t.index ["user_id", "postable_id"], name: "thredded_user_topic_read_states_user_postable", unique: true end + add_foreign_key "pictures", "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/pictures_controller_test.rb b/test/controllers/pictures_controller_test.rb new file mode 100644 index 0000000..7a9ac1f --- /dev/null +++ b/test/controllers/pictures_controller_test.rb @@ -0,0 +1,48 @@ +require "test_helper" + +class PicturesControllerTest < ActionDispatch::IntegrationTest + setup do + @picture = pictures(:one) + end + + test "should get index" do + get pictures_url + assert_response :success + end + + test "should get new" do + get new_picture_url + assert_response :success + end + + test "should create picture" do + assert_difference("Picture.count") do + post pictures_url, params: { picture: { member_id: @picture.member_id, picture: @picture.picture, text: @picture.text } } + end + + assert_redirected_to picture_url(Picture.last) + end + + test "should show picture" do + get picture_url(@picture) + assert_response :success + end + + test "should get edit" do + get edit_picture_url(@picture) + assert_response :success + end + + test "should update picture" do + patch picture_url(@picture), params: { picture: { member_id: @picture.member_id, picture: @picture.picture, text: @picture.text } } + assert_redirected_to picture_url(@picture) + end + + test "should destroy picture" do + assert_difference("Picture.count", -1) do + delete picture_url(@picture) + end + + assert_redirected_to pictures_url + end +end diff --git a/test/fixtures/pictures.yml b/test/fixtures/pictures.yml new file mode 100644 index 0000000..69e698a --- /dev/null +++ b/test/fixtures/pictures.yml @@ -0,0 +1,11 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + picture: MyString + text: MyString + member: one + +two: + picture: MyString + text: MyString + member: two diff --git a/test/models/picture_test.rb b/test/models/picture_test.rb new file mode 100644 index 0000000..49a5676 --- /dev/null +++ b/test/models/picture_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class PictureTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/policies/picture_policy_test.rb b/test/policies/picture_policy_test.rb new file mode 100644 index 0000000..69d184e --- /dev/null +++ b/test/policies/picture_policy_test.rb @@ -0,0 +1,18 @@ +require 'test_helper' + +class PicturePolicyTest < 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/pictures_test.rb b/test/system/pictures_test.rb new file mode 100644 index 0000000..c250e16 --- /dev/null +++ b/test/system/pictures_test.rb @@ -0,0 +1,45 @@ +require "application_system_test_case" + +class PicturesTest < ApplicationSystemTestCase + setup do + @picture = pictures(:one) + end + + test "visiting the index" do + visit pictures_url + assert_selector "h1", text: "Pictures" + end + + test "should create picture" do + visit pictures_url + click_on "New picture" + + fill_in "Member", with: @picture.member_id + fill_in "Picture", with: @picture.picture + fill_in "Text", with: @picture.text + click_on "Create Picture" + + assert_text "Picture was successfully created" + click_on "Back" + end + + test "should update Picture" do + visit picture_url(@picture) + click_on "Edit this picture", match: :first + + fill_in "Member", with: @picture.member_id + fill_in "Picture", with: @picture.picture + fill_in "Text", with: @picture.text + click_on "Update Picture" + + assert_text "Picture was successfully updated" + click_on "Back" + end + + test "should destroy Picture" do + visit picture_url(@picture) + click_on "Destroy this picture", match: :first + + assert_text "Picture was successfully destroyed" + end +end