From 714bd48e4042386cf2afea69a6c3bff121b79173 Mon Sep 17 00:00:00 2001 From: Zee Spencer Date: Fri, 30 Sep 2022 18:13:34 -0700 Subject: [PATCH] Marketplace: Products Controller persists Products! This starts to shift our Furniture and Item system away from an inheritance oriented rails-adjacent structure to a more Rails-forward structure. Furniture now places it's routes against the *room*, which allows it to support either Singleton-type Resource routes, or more traditional Resources routes. Further, it brings the `Placeable` interface a bit closer to ActiveRecord; which should reduce pain-points as we unwind the current overly-restrictive and complex Furniture/Item design. --- app/furniture/breakout_tables_by_jitsi.rb | 2 +- app/furniture/furniture.rb | 10 +++++++- app/furniture/marketplace.rb | 4 ++++ app/furniture/marketplace/product.rb | 1 + app/furniture/marketplace/product_policy.rb | 8 +++++++ .../marketplace/products_controller.rb | 14 +++++++++-- app/furniture/payment_form.rb | 2 +- app/furniture/placeable.rb | 17 +++++++++++--- app/furniture/spotlight.rb | 2 +- config/routes.rb | 3 ++- spec/factories/furniture/marketplace.rb | 18 +++++++++++++++ .../marketplace/products_request_spec.rb | 23 +++++++++++++++++++ 12 files changed, 94 insertions(+), 10 deletions(-) create mode 100644 app/furniture/marketplace/product_policy.rb create mode 100644 spec/factories/furniture/marketplace.rb create mode 100644 spec/furniture/marketplace/products_request_spec.rb diff --git a/app/furniture/breakout_tables_by_jitsi.rb b/app/furniture/breakout_tables_by_jitsi.rb index 152fce3f5..14ef97ba9 100644 --- a/app/furniture/breakout_tables_by_jitsi.rb +++ b/app/furniture/breakout_tables_by_jitsi.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class BreakoutTablesByJitsi - def self.append_routes(router) + def self.deprecated_append_routes(router) router.resources :breakout_tables_by_jitsi, only: [:show], controller: 'breakout_tables_by_jitsi_by_jitsi/' end include Placeable diff --git a/app/furniture/furniture.rb b/app/furniture/furniture.rb index 4f54e7ebe..daf203be8 100644 --- a/app/furniture/furniture.rb +++ b/app/furniture/furniture.rb @@ -14,7 +14,15 @@ module Furniture spotlight: Spotlight, }.freeze - # Appends each {Furniture}'s CRUD actions + # Appends each {Furniture}'s CRUD actions under a FurniturePlacement + # @deprecated + def self.deprecated_append_routes(routing_context) + REGISTRY.each_value do |furniture| + furniture.deprecated_append_routes(routing_context) if furniture.respond_to?(:deprecated_append_routes) + end + end + + # Appends each Furnitures CRUD actions within the {Room} def self.append_routes(routing_context) REGISTRY.each_value do |furniture| furniture.append_routes(routing_context) if furniture.respond_to?(:append_routes) diff --git a/app/furniture/marketplace.rb b/app/furniture/marketplace.rb index 17401ca6e..647451d31 100644 --- a/app/furniture/marketplace.rb +++ b/app/furniture/marketplace.rb @@ -6,4 +6,8 @@ def self.append_routes(router) router.resources :products, only: %i[create index], module: "marketplace" end end + + def products + Marketplace::Product.where(space: space) + end end diff --git a/app/furniture/marketplace/product.rb b/app/furniture/marketplace/product.rb index efb7233c1..921a3cbe5 100644 --- a/app/furniture/marketplace/product.rb +++ b/app/furniture/marketplace/product.rb @@ -1,5 +1,6 @@ class Marketplace class Product < ApplicationRecord self.table_name = 'marketplace_products' + belongs_to :space end end diff --git a/app/furniture/marketplace/product_policy.rb b/app/furniture/marketplace/product_policy.rb new file mode 100644 index 000000000..f10582837 --- /dev/null +++ b/app/furniture/marketplace/product_policy.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true +class Marketplace + class ProductPolicy < ApplicationPolicy + def permitted_attributes(_params) + %i[name description price_cents price_currency] + end + end +end diff --git a/app/furniture/marketplace/products_controller.rb b/app/furniture/marketplace/products_controller.rb index 699e6dd11..c7d92932b 100644 --- a/app/furniture/marketplace/products_controller.rb +++ b/app/furniture/marketplace/products_controller.rb @@ -1,6 +1,16 @@ class Marketplace - class ProductsController < ApplicationController + class ProductsController < FurnitureController + def create + product = marketplace.products.new(product_params) + product.save! + end - def create ; end + def marketplace + Marketplace.find_by(room: room) + end + + def product_params + policy(Marketplace::Product).permit(params.require(:product)) + end end end diff --git a/app/furniture/payment_form.rb b/app/furniture/payment_form.rb index 71ee388fb..1320cbd81 100644 --- a/app/furniture/payment_form.rb +++ b/app/furniture/payment_form.rb @@ -5,7 +5,7 @@ class PaymentForm include Placeable - def self.append_routes(router) + def self.deprecated_append_routes(router) router.scope module: 'payment_form' do router.resource :payment_form, only: [:show] do router.resources :payments, only: %i[create index] diff --git a/app/furniture/placeable.rb b/app/furniture/placeable.rb index 9c58f41ae..1301aa3d4 100644 --- a/app/furniture/placeable.rb +++ b/app/furniture/placeable.rb @@ -6,12 +6,23 @@ module Placeable # @return {FurniturePlacement} attr_accessor :placement - delegate :id, :room, :utilities, :persisted?, :save!, to: :placement + delegate :id, :room, :space, :utilities, :persisted?, :save!, to: :placement def self.included(placeable) placeable.include ActiveModel::Model placeable.include ActiveModel::Attributes placeable.include ActiveModel::AttributeAssignment + placeable.extend ClassMethods + end + + module ClassMethods + def find_by(room:) + room.furniture_placements.find_by(furniture_kind: furniture_kind).furniture + end + + def furniture_kind + name.demodulize.underscore + end end def settings @@ -19,10 +30,10 @@ def settings end def in_room_template - "#{self.class.name.demodulize.underscore}/in_room" + "#{self.class.furniture_kind}/in_room" end def form_template - "#{self.class.name.demodulize.underscore}/form" + "#{self.class.furniture_kind}/form" end end diff --git a/app/furniture/spotlight.rb b/app/furniture/spotlight.rb index 87405167a..5fac9587d 100644 --- a/app/furniture/spotlight.rb +++ b/app/furniture/spotlight.rb @@ -3,7 +3,7 @@ class Spotlight include Placeable - def self.append_routes(router) + def self.deprecated_append_routes(router) router.scope module: 'spotlight' do router.resource :spotlight, only: [:show] do router.resources :images, only: %i[create edit update] diff --git a/config/routes.rb b/config/routes.rb index a340484b2..ab34f3bbc 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -16,10 +16,11 @@ end resources :rooms, only: %i[show edit update new create destroy] do + Furniture.append_routes(self) resource :waiting_room, only: %i[show update] resources :furniture_placements, only: %i[create edit update destroy] resource :furniture, only: [] do - Furniture.append_routes(self) + Furniture.deprecated_append_routes(self) end end diff --git a/spec/factories/furniture/marketplace.rb b/spec/factories/furniture/marketplace.rb new file mode 100644 index 000000000..4a427a399 --- /dev/null +++ b/spec/factories/furniture/marketplace.rb @@ -0,0 +1,18 @@ +FactoryBot.define do + factory :marketplace do + transient do + room { build(:room) } + end + + placement do + association :furniture_placement, { furniture_kind: 'marketplace', room: room } + end + end + + factory :marketplace_product, class: 'Marketplace::Product' do + name { Faker::TvShows::DrWho.specie } + price_cents { Random.rand(1_00..9999_99) } + + association :space + end +end diff --git a/spec/furniture/marketplace/products_request_spec.rb b/spec/furniture/marketplace/products_request_spec.rb new file mode 100644 index 000000000..5eaf50fce --- /dev/null +++ b/spec/furniture/marketplace/products_request_spec.rb @@ -0,0 +1,23 @@ +require 'rails_helper' + +RSpec.describe Marketplace::ProductsController, type: :request do + let(:marketplace) { create(:marketplace)} + let(:space) { marketplace.space } + let(:room) { marketplace.room } + describe "POST /products" do + + it "Creates a Product in the Marketplace" do + attributes = attributes_for(:marketplace_product) + + expect do + post polymorphic_path([space, room, marketplace, :products]), params: { product: attributes } + end.to change(marketplace.products, :count).by(1) + + created_product = marketplace.products.last + expect(created_product.name).to eql(attributes[:name]) + expect(created_product.description).to eql(attributes[:description]) + expect(created_product.price_cents).to eql(attributes[:price_cents]) + expect(created_product.price_currency).to eql(Money.default_currency.to_s) + end + end +end \ No newline at end of file