From c38dc4661d1ecf21856525e8a1702fef8a6cfbf1 Mon Sep 17 00:00:00 2001 From: Mackenzie Morgan Date: Tue, 27 Jan 2015 00:54:05 -0500 Subject: [PATCH] basics of garden photos --- app/controllers/photos_controller.rb | 2 +- app/models/garden.rb | 15 +++ app/models/photo.rb | 4 +- app/views/gardens/show.html.haml | 15 +++ ...20150127043022_add_gardens_photos_table.rb | 9 ++ db/schema.rb | 105 ++++++++++-------- spec/controllers/photos_controller_spec.rb | 6 + spec/models/garden_spec.rb | 28 +++++ spec/models/photo_spec.rb | 29 ++++- 9 files changed, 160 insertions(+), 53 deletions(-) create mode 100644 db/migrate/20150127043022_add_gardens_photos_table.rb diff --git a/app/controllers/photos_controller.rb b/app/controllers/photos_controller.rb index 3fac4ea32..63672efe1 100644 --- a/app/controllers/photos_controller.rb +++ b/app/controllers/photos_controller.rb @@ -65,7 +65,7 @@ class PhotosController < ApplicationController # several models can have photos. we need to know what model and the id # for the entry to attach the photo to - valid_models = ["planting", "harvest"] + valid_models = ["planting", "harvest", "garden"] if params[:type] if valid_models.include?(params[:type]) if params[:id] diff --git a/app/models/garden.rb b/app/models/garden.rb index 61e51d97d..4e08a36d5 100644 --- a/app/models/garden.rb +++ b/app/models/garden.rb @@ -7,6 +7,17 @@ class Garden < ActiveRecord::Base has_many :plantings, -> { order(created_at: :desc) }, :dependent => :destroy has_many :crops, :through => :plantings + has_and_belongs_to_many :photos + + before_destroy do |garden| + photolist = garden.photos.to_a # save a temp copy of the photo list + garden.photos.clear # clear relationship b/w garden and photo + + photolist.each do |photo| + photo.destroy_if_unused + end + end + # set up geocoding geocoded_by :location after_validation :geocode @@ -83,4 +94,8 @@ class Garden < ActiveRecord::Base end end + def default_photo + return photos.first + end + end diff --git a/app/models/photo.rb b/app/models/photo.rb index 9ab411d09..54cc94de3 100644 --- a/app/models/photo.rb +++ b/app/models/photo.rb @@ -3,16 +3,18 @@ class Photo < ActiveRecord::Base has_and_belongs_to_many :plantings has_and_belongs_to_many :harvests + has_and_belongs_to_many :gardens before_destroy do |photo| photo.plantings.clear photo.harvests.clear + photo.gardens.clear end default_scope { order("created_at desc") } # remove photos that aren't used by anything def destroy_if_unused - unless plantings.size > 0 or harvests.size > 0 + unless plantings.size > 0 or harvests.size > 0 or gardens.size > 0 self.destroy end end diff --git a/app/views/gardens/show.html.haml b/app/views/gardens/show.html.haml index a0630d3a8..25c707fb3 100644 --- a/app/views/gardens/show.html.haml +++ b/app/views/gardens/show.html.haml @@ -29,6 +29,21 @@ :growstuff_markdown #{strip_tags @garden.description} + - if @garden.photos.count > 0 or (can? :edit, @garden and can? :create, Photo) + .row + %h2 Photos + + %ul.thumbnails + - @garden.photos.each do |p| + .col-md-2.six-across + = render :partial => 'photos/thumbnail', :locals => { :photo => p } + - if can? :create, Photo and can? :edit, @garden + .col-md-2 + .thumbnail(style='height: 220px') + %p{:style => 'text-align: center; padding-top: 50px'} + = link_to "Add photo", new_photo_path(:type => "garden", :id => @garden.id), :class => 'btn btn-primary' + + %h3 What's planted here? diff --git a/db/migrate/20150127043022_add_gardens_photos_table.rb b/db/migrate/20150127043022_add_gardens_photos_table.rb new file mode 100644 index 000000000..c0cfd76fc --- /dev/null +++ b/db/migrate/20150127043022_add_gardens_photos_table.rb @@ -0,0 +1,9 @@ +class AddGardensPhotosTable < ActiveRecord::Migration + def change + create_table :gardens_photos, :id => false do |t| + t.integer :photo_id + t.integer :garden_id + end + add_index(:gardens_photos, [:garden_id, :photo_id]) + end +end diff --git a/db/schema.rb b/db/schema.rb index 9c4137f40..9e593a422 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20141119130555) do +ActiveRecord::Schema.define(version: 20150127043022) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -20,16 +20,16 @@ ActiveRecord::Schema.define(version: 20141119130555) do t.string "name", null: false t.boolean "is_paid" t.boolean "is_permanent_paid" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end create_table "accounts", force: true do |t| t.integer "member_id", null: false t.integer "account_type_id" t.datetime "paid_until" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end create_table "alternate_names", force: true do |t| @@ -46,8 +46,8 @@ ActiveRecord::Schema.define(version: 20141119130555) do t.string "uid" t.string "token" t.string "secret" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "name" end @@ -57,15 +57,15 @@ ActiveRecord::Schema.define(version: 20141119130555) do t.integer "post_id", null: false t.integer "author_id", null: false t.text "body", null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end create_table "crops", force: true do |t| t.string "name", null: false t.string "en_wikipedia_url" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "slug" t.integer "parent_id" t.integer "plantings_count", default: 0 @@ -94,8 +94,8 @@ ActiveRecord::Schema.define(version: 20141119130555) do t.string "name", null: false t.text "description", null: false t.integer "owner_id", null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "slug" end @@ -105,8 +105,8 @@ ActiveRecord::Schema.define(version: 20141119130555) do t.string "name", null: false t.integer "owner_id" t.string "slug", null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.text "description" t.boolean "active", default: true t.string "location" @@ -116,9 +116,16 @@ ActiveRecord::Schema.define(version: 20141119130555) do t.string "area_unit" end - add_index "gardens", ["owner_id"], name: "index_gardens_on_owner_id", using: :btree + add_index "gardens", ["owner_id"], name: "index_gardens_on_user_id", using: :btree add_index "gardens", ["slug"], name: "index_gardens_on_slug", unique: true, using: :btree + create_table "gardens_photos", id: false, force: true do |t| + t.integer "photo_id" + t.integer "garden_id" + end + + add_index "gardens_photos", ["garden_id", "photo_id"], name: "index_gardens_photos_on_garden_id_and_photo_id", using: :btree + create_table "harvests", force: true do |t| t.integer "crop_id", null: false t.integer "owner_id", null: false @@ -126,8 +133,8 @@ ActiveRecord::Schema.define(version: 20141119130555) do t.decimal "quantity" t.string "unit" t.text "description" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "slug" t.decimal "weight_quantity" t.string "weight_unit" @@ -159,8 +166,8 @@ ActiveRecord::Schema.define(version: 20141119130555) do t.integer "failed_attempts", default: 0 t.string "unlock_token" t.datetime "locked_at" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "login_name" t.string "slug" t.boolean "tos_agreement" @@ -175,11 +182,11 @@ ActiveRecord::Schema.define(version: 20141119130555) do t.boolean "send_planting_reminder", default: true end - add_index "members", ["confirmation_token"], name: "index_members_on_confirmation_token", unique: true, using: :btree - add_index "members", ["email"], name: "index_members_on_email", unique: true, using: :btree - add_index "members", ["reset_password_token"], name: "index_members_on_reset_password_token", unique: true, using: :btree - add_index "members", ["slug"], name: "index_members_on_slug", unique: true, using: :btree - add_index "members", ["unlock_token"], name: "index_members_on_unlock_token", unique: true, using: :btree + add_index "members", ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true, using: :btree + add_index "members", ["email"], name: "index_users_on_email", unique: true, using: :btree + add_index "members", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree + add_index "members", ["slug"], name: "index_users_on_slug", unique: true, using: :btree + add_index "members", ["unlock_token"], name: "index_users_on_unlock_token", unique: true, using: :btree create_table "members_roles", id: false, force: true do |t| t.integer "member_id" @@ -193,8 +200,8 @@ ActiveRecord::Schema.define(version: 20141119130555) do t.text "body" t.boolean "read", default: false t.integer "post_id" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end create_table "order_items", force: true do |t| @@ -202,13 +209,13 @@ ActiveRecord::Schema.define(version: 20141119130555) do t.integer "product_id" t.integer "price" t.integer "quantity" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end create_table "orders", force: true do |t| - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.datetime "completed_at" t.integer "member_id" t.string "paypal_express_token" @@ -225,8 +232,8 @@ ActiveRecord::Schema.define(version: 20141119130555) do t.integer "owner_id", null: false t.string "thumbnail_url", null: false t.string "fullsize_url", null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "title", null: false t.string "license_name", null: false t.string "license_url" @@ -241,8 +248,8 @@ ActiveRecord::Schema.define(version: 20141119130555) do create_table "plant_parts", force: true do |t| t.string "name" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "slug" end @@ -252,8 +259,8 @@ ActiveRecord::Schema.define(version: 20141119130555) do t.date "planted_at" t.integer "quantity" t.text "description" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "slug" t.string "sunniness" t.string "planted_from" @@ -268,21 +275,21 @@ ActiveRecord::Schema.define(version: 20141119130555) do t.integer "author_id", null: false t.string "subject", null: false t.text "body", null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "slug" t.integer "forum_id" end - add_index "posts", ["created_at", "author_id"], name: "index_posts_on_created_at_and_author_id", using: :btree - add_index "posts", ["slug"], name: "index_posts_on_slug", unique: true, using: :btree + add_index "posts", ["created_at", "author_id"], name: "index_updates_on_created_at_and_user_id", using: :btree + add_index "posts", ["slug"], name: "index_updates_on_slug", unique: true, using: :btree create_table "products", force: true do |t| t.string "name", null: false t.text "description", null: false t.integer "min_price", null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.integer "account_type_id" t.integer "paid_months" t.integer "recommended_price" @@ -291,8 +298,8 @@ ActiveRecord::Schema.define(version: 20141119130555) do create_table "roles", force: true do |t| t.string "name", null: false t.text "description" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "slug" end @@ -301,8 +308,8 @@ ActiveRecord::Schema.define(version: 20141119130555) do create_table "scientific_names", force: true do |t| t.string "scientific_name", null: false t.integer "crop_id", null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.integer "creator_id" end @@ -312,8 +319,8 @@ ActiveRecord::Schema.define(version: 20141119130555) do t.text "description" t.integer "quantity" t.date "plant_before" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "tradable_to", default: "nowhere" t.string "slug" end diff --git a/spec/controllers/photos_controller_spec.rb b/spec/controllers/photos_controller_spec.rb index 2dd7a6a56..e231c8b96 100644 --- a/spec/controllers/photos_controller_spec.rb +++ b/spec/controllers/photos_controller_spec.rb @@ -48,6 +48,12 @@ describe PhotosController do assigns(:type).should eq "harvest" end + it "assigns a garden id" do + get :new, { :type => "garden", :id => 5 } + assigns(:id).should eq "5" + assigns(:type).should eq "garden" + end + it "assigns the current set as @current_set" do get :new, { :set => 'foo' } assigns(:current_set).should eq "foo" diff --git a/spec/models/garden_spec.rb b/spec/models/garden_spec.rb index 9cc868d34..7a6590596 100644 --- a/spec/models/garden_spec.rb +++ b/spec/models/garden_spec.rb @@ -206,4 +206,32 @@ describe Garden do p2.finished.should eq false end + context 'photos' do + before(:each) do + @garden = FactoryGirl.create(:garden) + @photo = FactoryGirl.create(:photo) + @garden.photos << @photo + end + + it 'has a photo' do + @garden.photos.first.should eq @photo + end + + it 'deletes association with photos when photo is deleted' do + @photo.destroy + @garden.reload + @garden.photos.should be_empty + end + + it 'has a default photo' do + @garden.default_photo.should eq @photo + end + + it 'chooses the most recent photo' do + @photo2 = FactoryGirl.create(:photo) + @garden.photos << @photo2 + @garden.default_photo.should eq @photo2 + end + end + end diff --git a/spec/models/photo_spec.rb b/spec/models/photo_spec.rb index 5a2099c7a..650f0f57c 100644 --- a/spec/models/photo_spec.rb +++ b/spec/models/photo_spec.rb @@ -6,6 +6,7 @@ describe Photo do let(:photo) { FactoryGirl.create(:photo) } let(:planting) { FactoryGirl.create(:planting) } let(:harvest) { FactoryGirl.create(:harvest) } + let(:garden) { FactoryGirl.create(:garden) } context "adds photos" do it 'to a planting' do @@ -19,6 +20,12 @@ describe Photo do expect(harvest.photos.count).to eq 1 expect(harvest.photos.first).to eq photo end + + it 'to a garden' do + garden.photos << photo + expect(garden.photos.count).to eq 1 + expect(garden.photos.first).to eq photo + end end context "removing photos" do @@ -34,6 +41,12 @@ describe Photo do expect(harvest.photos.count).to eq 0 end + it 'from a garden' do + garden.photos << photo + photo.destroy + expect(garden.photos.count).to eq 0 + end + it "automatically if unused" do photo.destroy_if_unused expect(lambda { photo.reload }).to raise_error ActiveRecord::RecordNotFound @@ -55,21 +68,33 @@ describe Photo do expect(lambda { photo.reload }).not_to raise_error end + it 'they are used by gardens but not plantings' do + garden.photos << photo + planting.photos << photo + planting.destroy # photo is now used by garden but not planting + photo.destroy_if_unused + expect(lambda { photo.reload }).not_to raise_error + end + it 'they are no longer used by anything' do planting.photos << photo harvest.photos << photo + garden.photos << photo expect(photo.plantings.size).to eq 1 expect(photo.harvests.size).to eq 1 + expect(photo.gardens.size).to eq 1 - planting.destroy # photo is still used by harvest + planting.destroy # photo is still used by harvest and garden photo.reload expect(photo.plantings.size).to eq 0 expect(photo.harvests.size).to eq 1 - harvest.destroy # photo is now no longer used by anything + harvest.destroy + garden.destroy # photo is now no longer used by anything expect(photo.plantings.size).to eq 0 expect(photo.harvests.size).to eq 0 + expect(photo.gardens.size).to eq 0 photo.destroy_if_unused expect(lambda { photo.reload }).to raise_error ActiveRecord::RecordNotFound end