diff options
author | Matthew Lemon <y@yulqen.org> | 2023-12-18 19:38:44 +0000 |
---|---|---|
committer | Matthew Lemon <y@yulqen.org> | 2023-12-18 19:38:44 +0000 |
commit | 8185939b2629581dd9264dbbc37f859e19436f31 (patch) | |
tree | fdbc4f11f8d6c911ac7ebc4563254ae5299db603 | |
parent | 1fe9bf5c59ba9d4df5d2c917896348a0e23613a0 (diff) |
wip: stuck on notnull error...
27 files changed, 451 insertions, 2 deletions
diff --git a/app/controllers/events_controller.rb b/app/controllers/events_controller.rb index 058486d..d819632 100644 --- a/app/controllers/events_controller.rb +++ b/app/controllers/events_controller.rb @@ -67,6 +67,6 @@ class EventsController < ApplicationController # Only allow a list of trusted parameters through. def event_params - params.require(:event).permit(:date, :name) + params.require(:event).permit(:date, :name, :organisation_id) end end diff --git a/app/controllers/organisations_controller.rb b/app/controllers/organisations_controller.rb new file mode 100644 index 0000000..dbff777 --- /dev/null +++ b/app/controllers/organisations_controller.rb @@ -0,0 +1,70 @@ +class OrganisationsController < ApplicationController + before_action :set_organisation, only: %i[ show edit update destroy ] + + # GET /organisations or /organisations.json + def index + @organisations = Organisation.all + end + + # GET /organisations/1 or /organisations/1.json + def show + end + + # GET /organisations/new + def new + @organisation = Organisation.new + end + + # GET /organisations/1/edit + def edit + end + + # POST /organisations or /organisations.json + def create + @organisation = Organisation.new(organisation_params) + + respond_to do |format| + if @organisation.save + format.html { redirect_to organisation_url(@organisation), notice: "Organisation was successfully created." } + format.json { render :show, status: :created, location: @organisation } + else + format.html { render :new, status: :unprocessable_entity } + format.json { render json: @organisation.errors, status: :unprocessable_entity } + end + end + end + + # PATCH/PUT /organisations/1 or /organisations/1.json + def update + respond_to do |format| + if @organisation.update(organisation_params) + format.html { redirect_to organisation_url(@organisation), notice: "Organisation was successfully updated." } + format.json { render :show, status: :ok, location: @organisation } + else + format.html { render :edit, status: :unprocessable_entity } + format.json { render json: @organisation.errors, status: :unprocessable_entity } + end + end + end + + # DELETE /organisations/1 or /organisations/1.json + def destroy + @organisation.destroy! + + respond_to do |format| + format.html { redirect_to organisations_url, notice: "Organisation was successfully destroyed." } + format.json { head :no_content } + end + end + + private + # Use callbacks to share common setup or constraints between actions. + def set_organisation + @organisation = Organisation.find(params[:id]) + end + + # Only allow a list of trusted parameters through. + def organisation_params + params.require(:organisation).permit(:name) + end +end diff --git a/app/helpers/organisations_helper.rb b/app/helpers/organisations_helper.rb new file mode 100644 index 0000000..1b84554 --- /dev/null +++ b/app/helpers/organisations_helper.rb @@ -0,0 +1,2 @@ +module OrganisationsHelper +end diff --git a/app/models/event.rb b/app/models/event.rb index 9dea7b8..aaa4e6e 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -2,6 +2,8 @@ class Event < ApplicationRecord validates :name, presence: true, length: { maximum: 50 } validates :date, presence: true + belongs_to :organisation, optional: true + def month_year_check(year, month) if self.date.year == year && self.date.month == month true diff --git a/app/models/organisation.rb b/app/models/organisation.rb new file mode 100644 index 0000000..aa67564 --- /dev/null +++ b/app/models/organisation.rb @@ -0,0 +1,3 @@ +class Organisation < ApplicationRecord + has_many :events +end diff --git a/app/views/events/_form.html.erb b/app/views/events/_form.html.erb index 2a41eec..98dd972 100644 --- a/app/views/events/_form.html.erb +++ b/app/views/events/_form.html.erb @@ -36,6 +36,11 @@ <%= form.label "Event name", style: "display: block" %> <%= form.text_field :name %> </div> + + <div> + <%= form.label "Organisation", style: "display: block" %> + <%= form.select :organisation, Organisation.all.collect { |o| [ o.name, o.id ] }, include_blank: true %> + </div> <div> <%= form.submit style: "background: green; color: white; margin-top: 1.1em;"%> diff --git a/app/views/organisations/_form.html.erb b/app/views/organisations/_form.html.erb new file mode 100644 index 0000000..ebe8ea3 --- /dev/null +++ b/app/views/organisations/_form.html.erb @@ -0,0 +1,22 @@ +<%= form_with(model: organisation) do |form| %> + <% if organisation.errors.any? %> + <div style="color: red"> + <h2><%= pluralize(organisation.errors.count, "error") %> prohibited this organisation from being saved:</h2> + + <ul> + <% organisation.errors.each do |error| %> + <li><%= error.full_message %></li> + <% end %> + </ul> + </div> + <% end %> + + <div> + <%= form.label :name, style: "display: block" %> + <%= form.text_field :name %> + </div> + + <div> + <%= form.submit %> + </div> +<% end %> diff --git a/app/views/organisations/_organisation.html.erb b/app/views/organisations/_organisation.html.erb new file mode 100644 index 0000000..c5ea553 --- /dev/null +++ b/app/views/organisations/_organisation.html.erb @@ -0,0 +1,7 @@ +<div id="<%= dom_id organisation %>"> + <p> + <strong>Name:</strong> + <%= organisation.name %> + </p> + +</div> diff --git a/app/views/organisations/_organisation.json.jbuilder b/app/views/organisations/_organisation.json.jbuilder new file mode 100644 index 0000000..e4d8f92 --- /dev/null +++ b/app/views/organisations/_organisation.json.jbuilder @@ -0,0 +1,2 @@ +json.extract! organisation, :id, :name, :created_at, :updated_at +json.url organisation_url(organisation, format: :json) diff --git a/app/views/organisations/edit.html.erb b/app/views/organisations/edit.html.erb new file mode 100644 index 0000000..95bea56 --- /dev/null +++ b/app/views/organisations/edit.html.erb @@ -0,0 +1,10 @@ +<h1>Editing organisation</h1> + +<%= render "form", organisation: @organisation %> + +<br> + +<div> + <%= link_to "Show this organisation", @organisation %> | + <%= link_to "Back to organisations", organisations_path %> +</div> diff --git a/app/views/organisations/index.html.erb b/app/views/organisations/index.html.erb new file mode 100644 index 0000000..45d5b16 --- /dev/null +++ b/app/views/organisations/index.html.erb @@ -0,0 +1,14 @@ +<p style="color: green"><%= notice %></p> + +<h1>Organisations</h1> + +<div id="organisations"> + <% @organisations.each do |organisation| %> + <%= render organisation %> + <p> + <%= link_to "Show this organisation", organisation %> + </p> + <% end %> +</div> + +<%= link_to "New organisation", new_organisation_path %> diff --git a/app/views/organisations/index.json.jbuilder b/app/views/organisations/index.json.jbuilder new file mode 100644 index 0000000..4490dc6 --- /dev/null +++ b/app/views/organisations/index.json.jbuilder @@ -0,0 +1 @@ +json.array! @organisations, partial: "organisations/organisation", as: :organisation diff --git a/app/views/organisations/new.html.erb b/app/views/organisations/new.html.erb new file mode 100644 index 0000000..a749bc8 --- /dev/null +++ b/app/views/organisations/new.html.erb @@ -0,0 +1,9 @@ +<h1>New organisation</h1> + +<%= render "form", organisation: @organisation %> + +<br> + +<div> + <%= link_to "Back to organisations", organisations_path %> +</div> diff --git a/app/views/organisations/show.html.erb b/app/views/organisations/show.html.erb new file mode 100644 index 0000000..3de432b --- /dev/null +++ b/app/views/organisations/show.html.erb @@ -0,0 +1,10 @@ +<p style="color: green"><%= notice %></p> + +<%= render @organisation %> + +<div> + <%= link_to "Edit this organisation", edit_organisation_path(@organisation) %> | + <%= link_to "Back to organisations", organisations_path %> + + <%= button_to "Destroy this organisation", @organisation, method: :delete %> +</div> diff --git a/app/views/organisations/show.json.jbuilder b/app/views/organisations/show.json.jbuilder new file mode 100644 index 0000000..c228d36 --- /dev/null +++ b/app/views/organisations/show.json.jbuilder @@ -0,0 +1 @@ +json.partial! "organisations/organisation", organisation: @organisation diff --git a/config/routes.rb b/config/routes.rb index 844c4a4..9a4a7ce 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,4 +1,5 @@ Rails.application.routes.draw do + resources :organisations resources :events #get 'pages/index' # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html diff --git a/db/migrate/20231218185814_create_organisations.rb b/db/migrate/20231218185814_create_organisations.rb new file mode 100644 index 0000000..e4dbda7 --- /dev/null +++ b/db/migrate/20231218185814_create_organisations.rb @@ -0,0 +1,9 @@ +class CreateOrganisations < ActiveRecord::Migration[7.1] + def change + create_table :organisations do |t| + t.string :name + + t.timestamps + end + end +end diff --git a/db/migrate/20231218190546_add_organisation_to_events.rb b/db/migrate/20231218190546_add_organisation_to_events.rb new file mode 100644 index 0000000..48b460b --- /dev/null +++ b/db/migrate/20231218190546_add_organisation_to_events.rb @@ -0,0 +1,5 @@ +class AddOrganisationToEvents < ActiveRecord::Migration[7.1] + def change + add_reference :events, :organisation, null: false, foreign_key: true + end +end diff --git a/db/schema.rb b/db/schema.rb index fd03a50..07579bb 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,12 +10,21 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2023_12_16_203855) do +ActiveRecord::Schema[7.1].define(version: 2023_12_18_190546) do create_table "events", force: :cascade do |t| t.date "date" t.string "name" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.integer "organisation_id", null: false + t.index ["organisation_id"], name: "index_events_on_organisation_id" end + create_table "organisations", force: :cascade do |t| + t.string "name" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + add_foreign_key "events", "organisations" end diff --git a/spec/helpers/organisations_helper_spec.rb b/spec/helpers/organisations_helper_spec.rb new file mode 100644 index 0000000..85ff232 --- /dev/null +++ b/spec/helpers/organisations_helper_spec.rb @@ -0,0 +1,15 @@ +require 'rails_helper' + +# Specs in this file have access to a helper object that includes +# the OrganisationsHelper. For example: +# +# describe OrganisationsHelper do +# describe "string concat" do +# it "concats two strings with spaces" do +# expect(helper.concat_strings("this","that")).to eq("this that") +# end +# end +# end +RSpec.describe OrganisationsHelper, type: :helper do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/models/organisation_spec.rb b/spec/models/organisation_spec.rb new file mode 100644 index 0000000..6f6cdca --- /dev/null +++ b/spec/models/organisation_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe Organisation, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/requests/organisations_spec.rb b/spec/requests/organisations_spec.rb new file mode 100644 index 0000000..669d7ec --- /dev/null +++ b/spec/requests/organisations_spec.rb @@ -0,0 +1,135 @@ +require 'rails_helper' + +# This spec was generated by rspec-rails when you ran the scaffold generator. +# It demonstrates how one might use RSpec to test the controller code that +# was generated by Rails when you ran the scaffold generator. +# +# It assumes that the implementation code is generated by the rails scaffold +# generator. If you are using any extension libraries to generate different +# controller code, this generated spec may or may not pass. +# +# It only uses APIs available in rails and/or rspec-rails. There are a number +# of tools you can use to make these specs even more expressive, but we're +# sticking to rails and rspec-rails APIs to keep things simple and stable. + +RSpec.describe "/organisations", type: :request do + + # This should return the minimal set of attributes required to create a valid + # Organisation. As you add validations to Organisation, be sure to + # adjust the attributes here as well. + let(:valid_attributes) { + skip("Add a hash of attributes valid for your model") + } + + let(:invalid_attributes) { + skip("Add a hash of attributes invalid for your model") + } + + describe "GET /index" do + it "renders a successful response" do + Organisation.create! valid_attributes + get organisations_url + expect(response).to be_successful + end + end + + describe "GET /show" do + it "renders a successful response" do + organisation = Organisation.create! valid_attributes + get organisation_url(organisation) + expect(response).to be_successful + end + end + + describe "GET /new" do + it "renders a successful response" do + get new_organisation_url + expect(response).to be_successful + end + end + + describe "GET /edit" do + it "renders a successful response" do + organisation = Organisation.create! valid_attributes + get edit_organisation_url(organisation) + expect(response).to be_successful + end + end + + describe "POST /create" do + context "with valid parameters" do + it "creates a new Organisation" do + expect { + post organisations_url, params: { organisation: valid_attributes } + }.to change(Organisation, :count).by(1) + end + + it "redirects to the created organisation" do + post organisations_url, params: { organisation: valid_attributes } + expect(response).to redirect_to(organisation_url(Organisation.last)) + end + end + + context "with invalid parameters" do + it "does not create a new Organisation" do + expect { + post organisations_url, params: { organisation: invalid_attributes } + }.to change(Organisation, :count).by(0) + end + + + it "renders a response with 422 status (i.e. to display the 'new' template)" do + post organisations_url, params: { organisation: invalid_attributes } + expect(response).to have_http_status(:unprocessable_entity) + end + + end + end + + describe "PATCH /update" do + context "with valid parameters" do + let(:new_attributes) { + skip("Add a hash of attributes valid for your model") + } + + it "updates the requested organisation" do + organisation = Organisation.create! valid_attributes + patch organisation_url(organisation), params: { organisation: new_attributes } + organisation.reload + skip("Add assertions for updated state") + end + + it "redirects to the organisation" do + organisation = Organisation.create! valid_attributes + patch organisation_url(organisation), params: { organisation: new_attributes } + organisation.reload + expect(response).to redirect_to(organisation_url(organisation)) + end + end + + context "with invalid parameters" do + + it "renders a response with 422 status (i.e. to display the 'edit' template)" do + organisation = Organisation.create! valid_attributes + patch organisation_url(organisation), params: { organisation: invalid_attributes } + expect(response).to have_http_status(:unprocessable_entity) + end + + end + end + + describe "DELETE /destroy" do + it "destroys the requested organisation" do + organisation = Organisation.create! valid_attributes + expect { + delete organisation_url(organisation) + }.to change(Organisation, :count).by(-1) + end + + it "redirects to the organisations list" do + organisation = Organisation.create! valid_attributes + delete organisation_url(organisation) + expect(response).to redirect_to(organisations_url) + end + end +end diff --git a/spec/routing/organisations_routing_spec.rb b/spec/routing/organisations_routing_spec.rb new file mode 100644 index 0000000..4892aae --- /dev/null +++ b/spec/routing/organisations_routing_spec.rb @@ -0,0 +1,38 @@ +require "rails_helper" + +RSpec.describe OrganisationsController, type: :routing do + describe "routing" do + it "routes to #index" do + expect(get: "/organisations").to route_to("organisations#index") + end + + it "routes to #new" do + expect(get: "/organisations/new").to route_to("organisations#new") + end + + it "routes to #show" do + expect(get: "/organisations/1").to route_to("organisations#show", id: "1") + end + + it "routes to #edit" do + expect(get: "/organisations/1/edit").to route_to("organisations#edit", id: "1") + end + + + it "routes to #create" do + expect(post: "/organisations").to route_to("organisations#create") + end + + it "routes to #update via PUT" do + expect(put: "/organisations/1").to route_to("organisations#update", id: "1") + end + + it "routes to #update via PATCH" do + expect(patch: "/organisations/1").to route_to("organisations#update", id: "1") + end + + it "routes to #destroy" do + expect(delete: "/organisations/1").to route_to("organisations#destroy", id: "1") + end + end +end diff --git a/spec/views/organisations/edit.html.erb_spec.rb b/spec/views/organisations/edit.html.erb_spec.rb new file mode 100644 index 0000000..bc410f5 --- /dev/null +++ b/spec/views/organisations/edit.html.erb_spec.rb @@ -0,0 +1,22 @@ +require 'rails_helper' + +RSpec.describe "organisations/edit", type: :view do + let(:organisation) { + Organisation.create!( + name: "MyString" + ) + } + + before(:each) do + assign(:organisation, organisation) + end + + it "renders the edit organisation form" do + render + + assert_select "form[action=?][method=?]", organisation_path(organisation), "post" do + + assert_select "input[name=?]", "organisation[name]" + end + end +end diff --git a/spec/views/organisations/index.html.erb_spec.rb b/spec/views/organisations/index.html.erb_spec.rb new file mode 100644 index 0000000..2755a02 --- /dev/null +++ b/spec/views/organisations/index.html.erb_spec.rb @@ -0,0 +1,20 @@ +require 'rails_helper' + +RSpec.describe "organisations/index", type: :view do + before(:each) do + assign(:organisations, [ + Organisation.create!( + name: "Name" + ), + Organisation.create!( + name: "Name" + ) + ]) + end + + it "renders a list of organisations" do + render + cell_selector = Rails::VERSION::STRING >= '7' ? 'div>p' : 'tr>td' + assert_select cell_selector, text: Regexp.new("Name".to_s), count: 2 + end +end diff --git a/spec/views/organisations/new.html.erb_spec.rb b/spec/views/organisations/new.html.erb_spec.rb new file mode 100644 index 0000000..948be9e --- /dev/null +++ b/spec/views/organisations/new.html.erb_spec.rb @@ -0,0 +1,18 @@ +require 'rails_helper' + +RSpec.describe "organisations/new", type: :view do + before(:each) do + assign(:organisation, Organisation.new( + name: "MyString" + )) + end + + it "renders new organisation form" do + render + + assert_select "form[action=?][method=?]", organisations_path, "post" do + + assert_select "input[name=?]", "organisation[name]" + end + end +end diff --git a/spec/views/organisations/show.html.erb_spec.rb b/spec/views/organisations/show.html.erb_spec.rb new file mode 100644 index 0000000..2974e87 --- /dev/null +++ b/spec/views/organisations/show.html.erb_spec.rb @@ -0,0 +1,14 @@ +require 'rails_helper' + +RSpec.describe "organisations/show", type: :view do + before(:each) do + assign(:organisation, Organisation.create!( + name: "Name" + )) + end + + it "renders attributes in <p>" do + render + expect(rendered).to match(/Name/) + end +end |