Rename containers to garden types

This commit is contained in:
Brenda Wallace
2019-03-26 20:48:51 +13:00
parent 02e0dd091a
commit 5395aefa66
37 changed files with 228 additions and 264 deletions

View File

@@ -1,56 +0,0 @@
class ContainersController < ApplicationController
# before_action :authenticate_member!, except: %i(index show)
load_and_authorize_resource
# GET /containers
def index
@containers = Container.all.paginate(page: params[:page])
end
# GET /containers/1
def show; end
# GET /containers/new
def new
@container = Container.new
end
# GET /containers/1/edit
def edit; end
# POST /containers
def create
@container = Container.new(container_params)
if @container.save
redirect_to @container, notice: 'Container was successfully created.'
else
render :new
end
end
# PATCH/PUT /containers/1
def update
if @container.update(container_params)
redirect_to @container, notice: 'Container was successfully updated.'
else
render :edit
end
end
# DELETE /containers/1
def destroy
@container.destroy
redirect_to containers_url, notice: 'Container was successfully destroyed.'
end
private
def set_container
@container = Container.find(params[:id])
end
def container_params
params.require(:container).permit(:description, :slug)
end
end

View File

@@ -0,0 +1,51 @@
class GardenTypesController < ApplicationController
respond_to :html, :json
load_and_authorize_resource
# GET /garden_types
def index
@garden_types = GardenType.all.paginate(page: params[:page])
respond_with @garden_types
end
# GET /garden_types/1
def show
respond_with @garden_type
end
# GET /garden_types/new
def new
@garden_type = GardenType.new
end
# GET /garden_types/1/edit
def edit; end
# POST /garden_types
def create
@garden_type = GardenType.create(garden_type_params)
respond_with(@garden_type)
end
# PATCH/PUT /garden_types/1
def update
@garden_type.update(garden_type_params)
respond_with @garden_type
end
# DELETE /garden_types/1
def destroy
@garden_type.destroy
respond_with @garden_type
end
private
def set_garden_type
@garden_type = GardenType.find(params[:id])
end
def garden_type_params
params.require(:garden_type).permit(:description, :slug)
end
end

View File

@@ -67,6 +67,6 @@ class GardensController < ApplicationController
def garden_params
params.require(:garden).permit(:name, :slug, :description, :active,
:location, :latitude, :longitude, :area, :area_unit, container_ids: [])
:location, :latitude, :longitude, :area, :area_unit, :garden_type_id)
end
end

View File

@@ -43,9 +43,9 @@ class Ability
an.crop.approved?
end
cannot :create, Container
cannot :update, Container
cannot :destroy, Container
cannot :create, GardenType
cannot :update, GardenType
cannot :destroy, GardenType
end
def member_abilities(member) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
@@ -129,9 +129,9 @@ class Ability
can :destroy, Follow
cannot :destroy, Follow, followed_id: member.id # can't unfollow yourself
cannot :create, Container
cannot :update, Container
cannot :destroy, Container
cannot :create, GardenType
cannot :update, GardenType
cannot :destroy, GardenType
end
def admin_abilities(member)

View File

@@ -1,19 +0,0 @@
class Container < ApplicationRecord
extend FriendlyId
friendly_id :description, use: %i(slugged finders)
has_many :plots, dependent: :destroy
has_many :gardens, through: :plots
validates :description, presence: true, uniqueness: true
def container_slug
description.gsub!(/[^A-Za-z ]/, '')
end
def subtitler(container)
num = container.gardens.uniq.count
s = num > 1 || num.zero? ? "s are" : " is"
"#{num} garden#{s} using this container"
end
end

View File

@@ -9,7 +9,7 @@ class Garden < ApplicationRecord
has_many :crops, through: :plantings
has_many :plots, dependent: :destroy
has_many :containers, through: :plots
belongs_to :garden_type, required: false
# set up geocoding
geocoded_by :location

19
app/models/garden_type.rb Normal file
View File

@@ -0,0 +1,19 @@
class GardenType < ApplicationRecord
extend FriendlyId
friendly_id :name, use: %i(slugged finders)
has_many :gardens
validates :name, presence: true, uniqueness: true
validates :slug, presence: true, uniqueness: true
def garden_type_slug
name.gsub!(/[^A-Za-z ]/, '')
end
def subtitler(container)
num = container.gardens.uniq.count
s = num > 1 || num.zero? ? "s are" : " is"
"#{num} garden#{s} using this container"
end
end

View File

@@ -1,4 +0,0 @@
class Plot < ApplicationRecord
belongs_to :garden
belongs_to :container
end

View File

@@ -1,4 +0,0 @@
.btn-group.container-actions
= render 'shared/buttons/edit', path: edit_container_path(container)
.pull-right
= render 'shared/buttons/delete', path: container_path(container)

View File

@@ -1,20 +0,0 @@
= form_for @container, html: { class: 'form-horizontal', role: "form" } do |f|
- if @container.errors.any?
#error_explanation
%h2= "#{pluralize(@container.errors.count, "error")} prohibited this container from being saved:"
%ul
- @container.errors.full_messages.each do |message|
%li= message
%h2 Basic information
.form-group
= f.label :description, class: 'control-label col-md-2'
.col-md-8
= f.text_field :description, class: 'form-control'
%span.help-block
The name for the container, i.e. "organic", in English (required).
.form-group
.form-actions.col-md-offset-2.col-md-8
= f.submit 'Save', class: 'btn btn-primary'

View File

@@ -1,7 +0,0 @@
- cache cache_key_for(Container, container.id) do
.thumbnail
.container-thumbnail
- if container
.containerinfo
.containername
= link_to container.description, container

View File

@@ -1,4 +0,0 @@
- content_for :title, "Edit Container"
- if can? :update, @container
= render 'form'

View File

@@ -1,17 +0,0 @@
- content_for :title, 'Containers'
%p
#{ENV['GROWSTUFF_SITE_NAME']} tracks who's growing what, where.
View any container page to see which of our members have used it.
.row
- @containers.each do |container|
.col-md-2.six-across
= render partial: "thumbnail", locals: { container: container }
- if can? :create, Container
%div
= link_to 'New Container', new_container_path, class: 'btn btn-primary'
.pagination
= will_paginate @containers

View File

@@ -1,4 +0,0 @@
- content_for :title, "New Container"
- if can? :create, @container
= render 'form'

View File

@@ -1,12 +0,0 @@
- content_for :title, @container.description.capitalize
- content_for :subtitle, @container.subtitler(@container)
- if can?(:create, @container) && can?(:edit, @container) && can?(:destroy, @container)
- content_for :buttonbar do
= render 'containers/actions', container: @container
- if @container.gardens.uniq.empty?
%p There are no gardens to display.
- else
- @container.gardens.uniq.each do |garden|
= render 'gardens/overview', garden: garden

View File

@@ -0,0 +1,4 @@
.btn-group.garden_type-actions
= render 'shared/buttons/edit', path: edit_garden_type_path(garden_type)
.pull-right
= render 'shared/buttons/delete', path: garden_type_path(garden_type)

View File

@@ -0,0 +1,20 @@
= form_for @garden_type, html: { class: 'form-horizontal', role: "form" } do |f|
- if @garden_type.errors.any?
#error_explanation
%h2= "#{pluralize(@garden_type.errors.count, "error")} prohibited this garden_type from being saved:"
%ul
- @garden_type.errors.full_messages.each do |message|
%li= message
%h2 Basic information
.form-group
= f.label :name, class: 'control-label col-md-2'
.col-md-8
= f.text_field :name, class: 'form-control'
%span.help-block
The name for the garden_type, i.e. "organic", in English (required).
.form-group
.form-actions.col-md-offset-2.col-md-8
= f.submit 'Save', class: 'btn btn-primary'

View File

@@ -0,0 +1,7 @@
- cache cache_key_for(GardenType, garden_type.id) do
.thumbnail
.garden_type-thumbnail
- if garden_type
.garden_typeinfo
.garden_typename
= link_to garden_type.name, garden_type

View File

@@ -0,0 +1,4 @@
- content_for :title, "Edit GardenType"
- if can? :update, @garden_type
= render 'form'

View File

@@ -0,0 +1,17 @@
- content_for :title, 'GardenTypes'
%p
#{ENV['GROWSTUFF_SITE_NAME']} tracks who's growing what, where.
View any garden_type page to see which of our members have used it.
.row
- @garden_types.each do |garden_type|
.col-md-2.six-across
= render partial: "thumbnail", locals: { garden_type: garden_type }
- if can? :create, GardenType
%div
= link_to 'New GardenType', new_garden_type_path, class: 'btn btn-primary'
.pagination
= will_paginate @garden_types

View File

@@ -0,0 +1,4 @@
- content_for :title, "New GardenType"
- if can? :create, @garden_type
= render 'form'

View File

@@ -0,0 +1,12 @@
- content_for :title, @garden_type.name.capitalize
- content_for :subtitle, @garden_type.subtitler(@garden_type)
- if can?(:create, @garden_type) && can?(:edit, @garden_type) && can?(:destroy, @garden_type)
- content_for :buttonbar do
= render 'garden_types/actions', garden_type: @garden_type
- if @garden_type.gardens.uniq.empty?
%p There are no gardens to display.
- else
- @garden_type.gardens.uniq.each do |garden|
= render 'gardens/overview', garden: garden

View File

@@ -44,11 +44,13 @@
= f.select(:area_unit, Garden::AREA_UNITS_VALUES, { include_blank: false }, class: 'form-control')
.form-group
= f.label :container, class: 'control-label col-md-2'
= f.label :garden_type, class: 'control-label col-md-2'
.col-md-2
= f.collection_check_boxes(:container_ids, Container.all, :id, :description) do |c|
= c.label class:"checkbox-inline" do
= c.check_box + c.text
= collection_select(:garden, :garden_type_id,
GardenType.all.order(:name),
:id, :name,
selected: @garden.garden_type_id,
class: 'form-control')
.form-group
= f.label :active, 'Active? ', class: 'control-label col-md-2'

View File

@@ -30,7 +30,7 @@
%li= link_to t('.seeds'), seeds_path
%li= link_to t('.plantings'), plantings_path
%li= link_to t('.harvests'), harvests_path
%li= link_to t('.containers'), containers_path
%li= link_to t('.garden_types'), garden_types_path
%li.dropdown<
%a.dropdown-toggle{ 'data-toggle': 'dropdown', href: members_path }
= t('.community')

View File

@@ -1,7 +1,7 @@
Rails.application.routes.draw do
get '/robots.txt' => 'robots#robots'
resources :containers
resources :garden_types
resources :plant_parts
devise_for :members, controllers: {

View File

@@ -1,15 +0,0 @@
class CreateContainers < ActiveRecord::Migration[4.2]
def change
create_table :containers do |t|
t.string :description
t.timestamps null: false
end
create_table :plots do |t|
t.references :garden, foreign_key: true
t.references :container, foreign_key: true
t.timestamps null: false
end
add_column :containers, :slug, :string
add_index :containers, :slug, unique: true
end
end

View File

@@ -0,0 +1,17 @@
class CreateGardenTypes < ActiveRecord::Migration[5.2]
def change
create_table :garden_types do |t|
t.text :name, null: false, unique: true
t.text :slug, null: false, unique: true
t.timestamps null: false
end
add_column :gardens, :garden_type_id, :integer
add_index :gardens, :garden_type_id
['organic', 'conventional', 'container', 'vertical', 'greenhouse', 'rooftop', 'no-dig', 'raised bed',
'wicking bed', 'permaculture', 'hydroponic', 'aquaponic', 'orchard', 'food forest',
'biodynamic'].each do |name|
say "Creating #{name}"
GardenType.create! name: name
end
end
end

View File

@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2019_03_17_023129) do
ActiveRecord::Schema.define(version: 2019_03_26_063855) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -153,14 +153,6 @@ ActiveRecord::Schema.define(version: 2019_03_17_023129) do
t.datetime "updated_at"
end
create_table "containers", id: :serial, force: :cascade do |t|
t.string "description"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "slug"
t.index ["slug"], name: "index_containers_on_slug", unique: true
end
create_table "crops", id: :serial, force: :cascade do |t|
t.string "name", null: false
t.string "en_wikipedia_url"
@@ -208,6 +200,13 @@ ActiveRecord::Schema.define(version: 2019_03_17_023129) do
t.index ["slug"], name: "index_forums_on_slug", unique: true
end
create_table "garden_types", force: :cascade do |t|
t.text "name", null: false
t.text "slug", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "gardens", id: :serial, force: :cascade do |t|
t.string "name", null: false
t.integer "owner_id"
@@ -221,6 +220,8 @@ ActiveRecord::Schema.define(version: 2019_03_17_023129) do
t.float "longitude"
t.decimal "area"
t.string "area_unit"
t.integer "garden_type_id"
t.index ["garden_type_id"], name: "index_gardens_on_garden_type_id"
t.index ["owner_id"], name: "index_gardens_on_owner_id"
t.index ["slug"], name: "index_gardens_on_slug", unique: true
end
@@ -402,13 +403,6 @@ ActiveRecord::Schema.define(version: 2019_03_17_023129) do
t.index ["slug"], name: "index_plantings_on_slug", unique: true
end
create_table "plots", id: :serial, force: :cascade do |t|
t.integer "garden_id"
t.integer "container_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "posts", id: :serial, force: :cascade do |t|
t.integer "author_id", null: false
t.string "subject", null: false
@@ -463,7 +457,5 @@ ActiveRecord::Schema.define(version: 2019_03_17_023129) do
add_foreign_key "photographings", "crops"
add_foreign_key "photographings", "photos"
add_foreign_key "plantings", "seeds", column: "parent_seed_id", name: "parent_seed", on_delete: :nullify
add_foreign_key "plots", "containers"
add_foreign_key "plots", "gardens"
add_foreign_key "seeds", "plantings", column: "parent_planting_id", name: "parent_planting", on_delete: :nullify
end

View File

@@ -1,5 +0,0 @@
FactoryBot.define do
factory :container do
description { "homemade swamp" }
end
end

View File

@@ -0,0 +1,5 @@
FactoryBot.define do
factory :garden_type do
name { "homemade swamp" }
end
end

View File

@@ -1,6 +0,0 @@
FactoryBot.define do
factory :plot do
garden { garden }
container { container }
end
end

View File

@@ -1,37 +0,0 @@
require 'rails_helper'
describe Container do
let(:owner) { FactoryBot.create(:member) }
let(:garden) { FactoryBot.create(:garden, owner: owner, name: 'Free Carrots') }
let(:container) { FactoryBot.create(:container, description: "fake hole in the ground") }
it "should have a description" do
container = FactoryBot.build(:container, description: "organic")
container.should be_valid
end
it "doesn't allow a nil description" do
container = FactoryBot.build(:container, description: nil)
container.should_not be_valid
end
it "doesn't allow a blank description" do
container = FactoryBot.build(:container, description: "")
container.should_not be_valid
end
it "doesn't allow a description with only spaces" do
container = FactoryBot.build(:container, description: " ")
container.should_not be_valid
end
it "destroys plots when deleted" do
container = FactoryBot.create(:container, description: "Massive Flower Pot")
@plot1 = FactoryBot.create(:plot, garden: garden, container: container)
@plot2 = FactoryBot.create(:plot, garden: garden, container: container)
container.plots.size.should eq(2)
all = Plot.count
container.destroy
Plot.count.should eq(all - 2)
end
end

View File

@@ -0,0 +1,37 @@
require 'rails_helper'
describe GardenType do
let(:owner) { FactoryBot.create(:member) }
let(:garden) { FactoryBot.create(:garden, owner: owner, name: 'Free Carrots') }
let(:container) { FactoryBot.create(:container, name: "fake hole in the ground") }
it "should have a name" do
container = FactoryBot.build(:container, name: "organic")
container.should be_valid
end
it "doesn't allow a nil name" do
container = FactoryBot.build(:container, name: nil)
container.should_not be_valid
end
it "doesn't allow a blank name" do
container = FactoryBot.build(:container, name: "")
container.should_not be_valid
end
it "doesn't allow a name with only spaces" do
container = FactoryBot.build(:container, name: " ")
container.should_not be_valid
end
it "destroys plots when deleted" do
container = FactoryBot.create(:container, name: "Massive Flower Pot")
@plot1 = FactoryBot.create(:plot, garden: garden, container: container)
@plot2 = FactoryBot.create(:plot, garden: garden, container: container)
container.plots.size.should eq(2)
all = Plot.count
container.destroy
Plot.count.should eq(all - 2)
end
end

View File

@@ -1,17 +0,0 @@
require 'rails_helper'
describe Plot do
let(:owner) { FactoryBot.create(:member) }
let(:garden) { FactoryBot.create(:garden) }
let(:container) { FactoryBot.create(:container) }
let(:plot) { FactoryBot.create(:plot, garden: garden, container: container) }
context "has valid attributes" do
it "should have a garden" do
plot.garden.description.should == "This is a **totally** cool garden"
end
it "should have a container" do
plot.container.description.should == "homemade swamp"
end
end
end

View File

@@ -1,9 +1,9 @@
require 'rails_helper'
RSpec.describe "Containers", type: :request do
describe "GET /containers" do
RSpec.describe "GardenTypes", type: :request do
describe "GET /garden_types" do
it "works! (now write some real specs)" do
get containers_path
get garden_types_path
expect(response).to have_http_status(200)
end
end

View File

@@ -10,7 +10,7 @@ describe "containers/edit" do
end
it "renders the edit container form" do
assert_select "form", action: containers_path, method: "post" do
assert_select "form", action: garden_types_path, method: "post" do
assert_select "input#container_description", name: "container[description]"
end
end

View File

@@ -10,7 +10,7 @@ describe "containers/new" do
end
it "renders new container form" do
assert_select "form", action: containers_path, method: "post" do
assert_select "form", action: garden_types_path, method: "post" do
assert_select "input#container_description", name: "container[description]"
end
end