diff options
author | Matthew Lemon <y@yulqen.org> | 2024-11-14 15:47:43 +0000 |
---|---|---|
committer | Matthew Lemon <y@yulqen.org> | 2024-11-14 15:47:43 +0000 |
commit | 6427b28c60c6ed0dfd637307d1ab4ffe65c1144d (patch) | |
tree | 156d280b94557f9606c053f6187aec2a21eb1b36 | |
parent | 1b64b0b709c5704de48120e20bdfad32f34b0b5d (diff) |
Adds ResourceType model
24 files changed, 314 insertions, 10 deletions
diff --git a/app/controllers/pdfresources_controller.rb b/app/controllers/pdfresources_controller.rb index adacc64..a710404 100644 --- a/app/controllers/pdfresources_controller.rb +++ b/app/controllers/pdfresources_controller.rb @@ -69,16 +69,17 @@ class PdfresourcesController < ApplicationController # Only allow a list of trusted parameters through. def pdfresource_params params.require(:pdfresource).permit( - :name, - :stripe_product_id, - :price, - :age_range, - :curriculum, - :feature_slot, - :description, + :name, + :stripe_product_id, + :price, + :age_range, + :curriculum, + :resource_type_id, + :feature_slot, + :description, :card_description, :credits, - pdfs: [], + pdfs: [], thumbnails: [] ) end diff --git a/app/controllers/resource_types_controller.rb b/app/controllers/resource_types_controller.rb new file mode 100644 index 0000000..fdfb791 --- /dev/null +++ b/app/controllers/resource_types_controller.rb @@ -0,0 +1,78 @@ +class ResourceTypesController < ApplicationController + before_action :set_resource_type, only: %i[ show edit update destroy ] + before_action :require_admin, only: %i[ new create update destroy ] + + # GET /resource_types or /resource_types.json + def index + @resource_types = ResourceType.all + end + + # GET /resource_types/1 or /resource_types/1.json + def show + end + + # GET /resource_types/new + def new + @resource_type = ResourceType.new + end + + # GET /resource_types/1/edit + def edit + end + + # POST /resource_types or /resource_types.json + def create + @resource_type = ResourceType.new(resource_type_params) + + respond_to do |format| + if @resource_type.save + format.html { redirect_to @resource_type, notice: "Resource type was successfully created." } + format.json { render :show, status: :created, location: @resource_type } + else + format.html { render :new, status: :unprocessable_entity } + format.json { render json: @resource_type.errors, status: :unprocessable_entity } + end + end + end + + # PATCH/PUT /resource_types/1 or /resource_types/1.json + def update + respond_to do |format| + if @resource_type.update(resource_type_params) + format.html { redirect_to @resource_type, notice: "Resource type was successfully updated." } + format.json { render :show, status: :ok, location: @resource_type } + else + format.html { render :edit, status: :unprocessable_entity } + format.json { render json: @resource_type.errors, status: :unprocessable_entity } + end + end + end + + # DELETE /resource_types/1 or /resource_types/1.json + def destroy + @resource_type.destroy! + + respond_to do |format| + format.html { redirect_to resource_types_path, status: :see_other, notice: "Resource type was successfully destroyed." } + format.json { head :no_content } + end + end + + private + # Use callbacks to share common setup or constraints between actions. + def set_resource_type + @resource_type = ResourceType.find(params.expect(:id)) + end + + # Only allow a list of trusted parameters through. + def resource_type_params + params.expect(resource_type: [ :name ]) + end + + # must be admin! + def require_admin + unless Current.session.user&.is_admin + redirect_to root_path, notice: "You must be an admin to perform this action." + end + end +end diff --git a/app/helpers/resource_types_helper.rb b/app/helpers/resource_types_helper.rb new file mode 100644 index 0000000..0a02a03 --- /dev/null +++ b/app/helpers/resource_types_helper.rb @@ -0,0 +1,2 @@ +module ResourceTypesHelper +end diff --git a/app/models/pdfresource.rb b/app/models/pdfresource.rb index 86e600c..4fa2292 100644 --- a/app/models/pdfresource.rb +++ b/app/models/pdfresource.rb @@ -2,6 +2,7 @@ class Pdfresource < ApplicationRecord has_many_attached :pdfs has_many_attached :thumbnails has_many_attached :pdf_snapshots + belongs_to :resource_type validates :feature_slot, numericality: { only_integer: true, greater_than_or_equal_to: 1, less_than_or_equal_to: 3, allow_nil: true }, allow_nil: true diff --git a/app/models/resource_type.rb b/app/models/resource_type.rb new file mode 100644 index 0000000..066a734 --- /dev/null +++ b/app/models/resource_type.rb @@ -0,0 +1,3 @@ +class ResourceType < ApplicationRecord + has_many :pdfresources +end diff --git a/app/views/pdfresources/_form.html.erb b/app/views/pdfresources/_form.html.erb index 1ad8fb1..a15bd67 100644 --- a/app/views/pdfresources/_form.html.erb +++ b/app/views/pdfresources/_form.html.erb @@ -90,6 +90,10 @@ <p class="text-sm text-gray-700">Number of credits required to purchase this resource.</p> </div> + <div class="my-5"> + <%= required_label_tag(form, :resource_type) %> + <%= form.collection_select :resource_type_id, ResourceType.all, :id, :name, {}, class: "block shadow rounded-md border border-gray-400 outline-none px-3 py-2 mt-2 w-full" %> + </div> <div class="my-5"> <%= form.label :stripe_product_id, "Stripe Product ID", class: "font-bold" %> diff --git a/app/views/pdfresources/_pdfresource.html.erb b/app/views/pdfresources/_pdfresource.html.erb index 12b2b58..8c96080 100644 --- a/app/views/pdfresources/_pdfresource.html.erb +++ b/app/views/pdfresources/_pdfresource.html.erb @@ -4,7 +4,7 @@ </div> <p class="my-5"> - <strong class="block font-bold mb-2"><%= pdfresource.name %></strong> + <%= link_to pdfresource.name, pdfresource, class: "text-blue-500 font-bold" %> </p> <div class="px-6 pt-4 pb-2"> @@ -39,6 +39,10 @@ <% end %> </div> + <p class="my-5"> + <strong class="block font-medium mb-1">Resource type:</strong> + <%= pdfresource.resource_type&.name if pdfresource.respond_to?(:resource_type) %> + </p> <p class="my-5"> <strong class="block font-medium mb-1">Price:</strong> diff --git a/app/views/resource_types/_form.html.erb b/app/views/resource_types/_form.html.erb new file mode 100644 index 0000000..5675729 --- /dev/null +++ b/app/views/resource_types/_form.html.erb @@ -0,0 +1,22 @@ +<%= form_with(model: resource_type, class: "contents") do |form| %> + <% if resource_type.errors.any? %> + <div id="error_explanation" class="bg-red-50 text-red-500 px-3 py-2 font-medium rounded-lg mt-3"> + <h2><%= pluralize(resource_type.errors.count, "error") %> prohibited this resource_type from being saved:</h2> + + <ul> + <% resource_type.errors.each do |error| %> + <li><%= error.full_message %></li> + <% end %> + </ul> + </div> + <% end %> + + <div class="my-5"> + <%= form.label :name %> + <%= form.text_field :name, class: "block shadow rounded-md border border-gray-400 outline-none px-3 py-2 mt-2 w-full" %> + </div> + + <div class="inline"> + <%= form.submit class: "rounded-lg py-3 px-5 bg-blue-600 text-white inline-block font-medium cursor-pointer" %> + </div> +<% end %> diff --git a/app/views/resource_types/_resource_type.html.erb b/app/views/resource_types/_resource_type.html.erb new file mode 100644 index 0000000..b144a58 --- /dev/null +++ b/app/views/resource_types/_resource_type.html.erb @@ -0,0 +1,7 @@ +<div id="<%= dom_id resource_type %>"> + <p class="my-5"> + <strong class="block font-medium mb-1">Name:</strong> + <%= resource_type.name %> + </p> + +</div> diff --git a/app/views/resource_types/_resource_type.json.jbuilder b/app/views/resource_types/_resource_type.json.jbuilder new file mode 100644 index 0000000..18f57c5 --- /dev/null +++ b/app/views/resource_types/_resource_type.json.jbuilder @@ -0,0 +1,2 @@ +json.extract! resource_type, :id, :name, :created_at, :updated_at +json.url resource_type_url(resource_type, format: :json) diff --git a/app/views/resource_types/edit.html.erb b/app/views/resource_types/edit.html.erb new file mode 100644 index 0000000..fa2bc6b --- /dev/null +++ b/app/views/resource_types/edit.html.erb @@ -0,0 +1,8 @@ +<div class="mx-auto md:w-2/3 w-full"> + <h1 class="font-bold text-4xl">Editing resource type</h1> + + <%= render "form", resource_type: @resource_type %> + + <%= link_to "Show this resource type", @resource_type, class: "ml-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium" %> + <%= link_to "Back to resource types", resource_types_path, class: "ml-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium" %> +</div> diff --git a/app/views/resource_types/index.html.erb b/app/views/resource_types/index.html.erb new file mode 100644 index 0000000..417e04e --- /dev/null +++ b/app/views/resource_types/index.html.erb @@ -0,0 +1,21 @@ +<div class="w-full"> + <% if notice.present? %> + <p class="py-2 px-3 bg-green-50 mb-5 text-green-500 font-medium rounded-lg inline-block" id="notice"><%= notice %></p> + <% end %> + + <% content_for :title, "Resource types" %> + + <div class="flex justify-between items-center"> + <h1 class="font-bold text-4xl">Resource types</h1> + <%= link_to "New resource type", new_resource_type_path, class: "rounded-lg py-3 px-5 bg-blue-600 text-white block font-medium" %> + </div> + + <div id="resource_types" class="min-w-full"> + <% @resource_types.each do |resource_type| %> + <%= render resource_type %> + <p> + <%= link_to "Show this resource type", resource_type, class: "ml-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium" %> + </p> + <% end %> + </div> +</div> diff --git a/app/views/resource_types/index.json.jbuilder b/app/views/resource_types/index.json.jbuilder new file mode 100644 index 0000000..7f19801 --- /dev/null +++ b/app/views/resource_types/index.json.jbuilder @@ -0,0 +1 @@ +json.array! @resource_types, partial: "resource_types/resource_type", as: :resource_type diff --git a/app/views/resource_types/new.html.erb b/app/views/resource_types/new.html.erb new file mode 100644 index 0000000..0c15be3 --- /dev/null +++ b/app/views/resource_types/new.html.erb @@ -0,0 +1,7 @@ +<div class="mx-auto md:w-1/2 w-full"> + <h1 class="font-bold text-4xl">New resource type</h1> + + <%= render "form", resource_type: @resource_type %> + + <%= link_to "Back to resource types", resource_types_path, class: "ml-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium" %> +</div> diff --git a/app/views/resource_types/show.html.erb b/app/views/resource_types/show.html.erb new file mode 100644 index 0000000..463156d --- /dev/null +++ b/app/views/resource_types/show.html.erb @@ -0,0 +1,15 @@ +<div class="mx-auto md:w-2/3 w-full flex"> + <div class="mx-auto"> + <% if notice.present? %> + <p class="py-2 px-3 bg-green-50 mb-5 text-green-500 font-medium rounded-lg inline-block" id="notice"><%= notice %></p> + <% end %> + + <%= render @resource_type %> + + <%= link_to "Edit this resource type", edit_resource_type_path(@resource_type), class: "mt-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium" %> + <%= link_to "Back to resource types", resource_types_path, class: "ml-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium" %> + <div class="inline-block ml-2"> + <%= button_to "Destroy this resource type", @resource_type, method: :delete, class: "mt-2 rounded-lg py-3 px-5 bg-gray-100 font-medium" %> + </div> + </div> +</div> diff --git a/app/views/resource_types/show.json.jbuilder b/app/views/resource_types/show.json.jbuilder new file mode 100644 index 0000000..0e77d2a --- /dev/null +++ b/app/views/resource_types/show.json.jbuilder @@ -0,0 +1 @@ +json.partial! "resource_types/resource_type", resource_type: @resource_type diff --git a/config/routes.rb b/config/routes.rb index 3cf676f..1e8b325 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,4 +1,5 @@ Rails.application.routes.draw do + resources :resource_types resources :pdfresources resources :users resource :session diff --git a/db/migrate/20241114152218_create_resource_types.rb b/db/migrate/20241114152218_create_resource_types.rb new file mode 100644 index 0000000..f7f9de6 --- /dev/null +++ b/db/migrate/20241114152218_create_resource_types.rb @@ -0,0 +1,9 @@ +class CreateResourceTypes < ActiveRecord::Migration[8.0] + def change + create_table :resource_types do |t| + t.string :name + + t.timestamps + end + end +end diff --git a/db/migrate/20241114152810_add_resource_type_to_pdf_resource.rb b/db/migrate/20241114152810_add_resource_type_to_pdf_resource.rb new file mode 100644 index 0000000..e1c853b --- /dev/null +++ b/db/migrate/20241114152810_add_resource_type_to_pdf_resource.rb @@ -0,0 +1,5 @@ +class AddResourceTypeToPdfResource < ActiveRecord::Migration[8.0] + def change + add_reference :pdfresources, :resource_type, foreign_key: true + end +end diff --git a/db/schema.rb b/db/schema.rb index 61a7f3a..e09d8c2 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[8.0].define(version: 2024_11_14_105702) do +ActiveRecord::Schema[8.0].define(version: 2024_11_14_152810) do create_table "active_storage_attachments", force: :cascade do |t| t.string "name", null: false t.string "record_type", null: false @@ -51,6 +51,14 @@ ActiveRecord::Schema[8.0].define(version: 2024_11_14_105702) do t.datetime "created_at", null: false t.datetime "updated_at", null: false t.integer "credits" + t.integer "resource_type_id" + t.index ["resource_type_id"], name: "index_pdfresources_on_resource_type_id" + end + + create_table "resource_types", force: :cascade do |t| + t.string "name" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end create_table "sessions", force: :cascade do |t| @@ -75,5 +83,6 @@ ActiveRecord::Schema[8.0].define(version: 2024_11_14_105702) do add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id" add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id" + add_foreign_key "pdfresources", "resource_types" add_foreign_key "sessions", "users" end diff --git a/test/controllers/resource_types_controller_test.rb b/test/controllers/resource_types_controller_test.rb new file mode 100644 index 0000000..c5621ab --- /dev/null +++ b/test/controllers/resource_types_controller_test.rb @@ -0,0 +1,48 @@ +require "test_helper" + +class ResourceTypesControllerTest < ActionDispatch::IntegrationTest + setup do + @resource_type = resource_types(:one) + end + + test "should get index" do + get resource_types_url + assert_response :success + end + + test "should get new" do + get new_resource_type_url + assert_response :success + end + + test "should create resource_type" do + assert_difference("ResourceType.count") do + post resource_types_url, params: { resource_type: { name: @resource_type.name } } + end + + assert_redirected_to resource_type_url(ResourceType.last) + end + + test "should show resource_type" do + get resource_type_url(@resource_type) + assert_response :success + end + + test "should get edit" do + get edit_resource_type_url(@resource_type) + assert_response :success + end + + test "should update resource_type" do + patch resource_type_url(@resource_type), params: { resource_type: { name: @resource_type.name } } + assert_redirected_to resource_type_url(@resource_type) + end + + test "should destroy resource_type" do + assert_difference("ResourceType.count", -1) do + delete resource_type_url(@resource_type) + end + + assert_redirected_to resource_types_url + end +end diff --git a/test/fixtures/resource_types.yml b/test/fixtures/resource_types.yml new file mode 100644 index 0000000..7d41224 --- /dev/null +++ b/test/fixtures/resource_types.yml @@ -0,0 +1,7 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + name: MyString + +two: + name: MyString diff --git a/test/models/resource_type_test.rb b/test/models/resource_type_test.rb new file mode 100644 index 0000000..43ef137 --- /dev/null +++ b/test/models/resource_type_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class ResourceTypeTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/system/resource_types_test.rb b/test/system/resource_types_test.rb new file mode 100644 index 0000000..54fc45f --- /dev/null +++ b/test/system/resource_types_test.rb @@ -0,0 +1,41 @@ +require "application_system_test_case" + +class ResourceTypesTest < ApplicationSystemTestCase + setup do + @resource_type = resource_types(:one) + end + + test "visiting the index" do + visit resource_types_url + assert_selector "h1", text: "Resource types" + end + + test "should create resource type" do + visit resource_types_url + click_on "New resource type" + + fill_in "Name", with: @resource_type.name + click_on "Create Resource type" + + assert_text "Resource type was successfully created" + click_on "Back" + end + + test "should update Resource type" do + visit resource_type_url(@resource_type) + click_on "Edit this resource type", match: :first + + fill_in "Name", with: @resource_type.name + click_on "Update Resource type" + + assert_text "Resource type was successfully updated" + click_on "Back" + end + + test "should destroy Resource type" do + visit resource_type_url(@resource_type) + click_on "Destroy this resource type", match: :first + + assert_text "Resource type was successfully destroyed" + end +end |