From d014343667179da4a700108f698f5ad50da8e547 Mon Sep 17 00:00:00 2001 From: Skud Date: Mon, 16 Sep 2013 15:33:34 +1000 Subject: [PATCH 01/28] A basic implementation of a CSV dump for crops --- Gemfile | 2 + Gemfile.lock | 3 ++ app/controllers/crops_controller.rb | 9 +++- app/views/crops/index.csv.shaper | 69 +++++++++++++++++++++++++++++ 4 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 app/views/crops/index.csv.shaper diff --git a/Gemfile b/Gemfile index 9d6015b65..357d3522e 100644 --- a/Gemfile +++ b/Gemfile @@ -14,6 +14,8 @@ gem 'cancan' # for checking member privileges gem 'gibbon' # for Mailchimp newsletter subscriptions +gem 'csv_shaper' # CSV export + # vendored activemerchant for testing- needed for bogus paypal # gateway monkeypatch gem 'activemerchant', '1.33.0', diff --git a/Gemfile.lock b/Gemfile.lock index f82f5f9fd..b86dd6b17 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -88,6 +88,8 @@ GEM rest-client simplecov (>= 0.7) thor + csv_shaper (1.0.0) + activesupport (>= 3.0.0) dalli (2.6.4) debugger (1.6.1) columnize (>= 0.3.1) @@ -260,6 +262,7 @@ DEPENDENCIES coffee-rails (~> 3.2.1) compass-rails (~> 1.0.3) coveralls + csv_shaper dalli debugger devise diff --git a/app/controllers/crops_controller.rb b/app/controllers/crops_controller.rb index 29725d959..0892dbc4c 100644 --- a/app/controllers/crops_controller.rb +++ b/app/controllers/crops_controller.rb @@ -10,9 +10,14 @@ class CropsController < ApplicationController @crops = Crop.includes(:scientific_names, {:plantings => :photos}).paginate(:page => params[:page]) respond_to do |format| - format.html # index.html.haml - format.json { render json: @crops } + format.html + format.json { render :json => @crops } format.rss { render :layout => false } + format.csv do + @filename = "Growstuff-Crops-#{Time.zone.now.to_s(:number)}" + @crops = Crop.all + render :csv => @crops + end end end diff --git a/app/views/crops/index.csv.shaper b/app/views/crops/index.csv.shaper new file mode 100644 index 000000000..0954592a1 --- /dev/null +++ b/app/views/crops/index.csv.shaper @@ -0,0 +1,69 @@ +csv.headers :id, :system_name, + :growstuff_url, :en_wikipedia_url, + :default_scientific_name, + :scientific_name_count, + :parent_crop_id, :parent_crop_name, + :plantings_count, + :seeds_count, + :recommended_sunniness, + :planted_in_sun, + :planted_in_semi_shade, + :planted_in_shade, + :plant_from_recommendation, + :planted_from_seed, + :planted_from_seedling, + :planted_from_cutting, + :planted_from_root_division, + :planted_from_runner, + :planted_from_bulb, + :planted_from_bare_root_plant, + :planted_from_advanced_plant, + :planted_from_graft, + :planted_from_layering + +@crops.each do |c| + csv.row c do |csv, crop| + csv.cells :id, :system_name, :en_wikipedia_url + csv.cell :growstuff_url, crop_url(c) + + if c.scientific_names.any? + csv.cell :default_scientific_name, c.default_scientific_name + csv.cell :scientific_name_count, c.scientific_names.count + end + + if c.parent + csv.cell :parent_crop_id, c.parent.id + csv.cell :parent_crop_name, c.parent.system_name + end + + csv.cell :plantings_count || 0 + csv.cell :seeds_count, c.seeds.count + + sunniness = c.sunniness + sunniness_rec = sunniness.max_by{|k,v| v} + if sunniness_rec + csv.cell :recommended_sunniness, sunniness_rec[0] + end + csv.cell :planted_in_sun, sunniness['sun'] + csv.cell :planted_in_semi_shade, sunniness['semi_shade'] + csv.cell :planted_in_shade, sunniness['shade'] + + planted_from = c.planted_from + planted_from_rec = planted_from.max_by{|k,v| v} + if planted_from_rec + csv.cell :plant_from_recommendation, planted_from_rec[0] + end + + csv.cell :planted_from_seed, planted_from['seed'] + csv.cell :planted_from_seedling, planted_from['seedling'] + csv.cell :planted_from_cutting, planted_from['cutting'] + csv.cell :planted_from_root_division, planted_from['root division'] + csv.cell :planted_from_runner, planted_from['runner'] + csv.cell :planted_from_bulb, planted_from['bulb'] + csv.cell :planted_from_bare_root_plant, planted_from['bare root plant'] + csv.cell :planted_from_advanced_plant, planted_from['advanced plant'] + csv.cell :planted_from_graft, planted_from['graft'] + csv.cell :planted_from_layering, planted_from['layering'] + + end +end From 24255411c9d5907ebb6e8fcb39b6bca1833559d9 Mon Sep 17 00:00:00 2001 From: Skud Date: Mon, 16 Sep 2013 17:04:39 +1000 Subject: [PATCH 02/28] added dates created/modified to crops csv --- app/controllers/crops_controller.rb | 4 ++-- app/views/crops/index.csv.shaper | 7 ++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/app/controllers/crops_controller.rb b/app/controllers/crops_controller.rb index 0892dbc4c..0892acb33 100644 --- a/app/controllers/crops_controller.rb +++ b/app/controllers/crops_controller.rb @@ -14,8 +14,8 @@ class CropsController < ApplicationController format.json { render :json => @crops } format.rss { render :layout => false } format.csv do - @filename = "Growstuff-Crops-#{Time.zone.now.to_s(:number)}" - @crops = Crop.all + @filename = "Growstuff-Crops-#{Time.zone.now.to_s(:number)}.csv" + @crops = Crop.includes(:scientific_names, :plantings, :seeds) render :csv => @crops end end diff --git a/app/views/crops/index.csv.shaper b/app/views/crops/index.csv.shaper index 0954592a1..456e2cb7e 100644 --- a/app/views/crops/index.csv.shaper +++ b/app/views/crops/index.csv.shaper @@ -19,7 +19,9 @@ csv.headers :id, :system_name, :planted_from_bare_root_plant, :planted_from_advanced_plant, :planted_from_graft, - :planted_from_layering + :planted_from_layering, + :date_added, + :last_modified @crops.each do |c| csv.row c do |csv, crop| @@ -65,5 +67,8 @@ csv.headers :id, :system_name, csv.cell :planted_from_graft, planted_from['graft'] csv.cell :planted_from_layering, planted_from['layering'] + csv.cell :date_added, c.created_at.to_s(:db) + csv.cell :last_modified, c.updated_at.to_s(:db) + end end From 37383ba451186d8829bd3b0fd26e536426967a02 Mon Sep 17 00:00:00 2001 From: Skud Date: Tue, 17 Sep 2013 15:39:25 +1000 Subject: [PATCH 03/28] rails g scaffold Harvest... --- app/assets/javascripts/harvests.js.coffee | 3 + app/controllers/harvests_controller.rb | 83 ++++++++++ app/helpers/harvests_helper.rb | 2 + app/models/harvest.rb | 3 + app/views/harvests/_form.html.haml | 28 ++++ app/views/harvests/edit.html.haml | 7 + app/views/harvests/index.html.haml | 29 ++++ app/views/harvests/new.html.haml | 5 + app/views/harvests/show.html.haml | 24 +++ config/routes.rb | 3 + db/migrate/20130917053547_create_harvests.rb | 14 ++ db/schema.rb | 13 +- spec/controllers/harvests_controller_spec.rb | 164 +++++++++++++++++++ spec/factories/harvests.rb | 12 ++ spec/helpers/harvests_helper_spec.rb | 15 ++ spec/models/harvest_spec.rb | 5 + spec/requests/harvests_spec.rb | 11 ++ spec/routing/harvests_routing_spec.rb | 35 ++++ spec/views/harvests/edit.html.haml_spec.rb | 26 +++ spec/views/harvests/index.html.haml_spec.rb | 32 ++++ spec/views/harvests/new.html.haml_spec.rb | 26 +++ spec/views/harvests/show.html.haml_spec.rb | 23 +++ 22 files changed, 562 insertions(+), 1 deletion(-) create mode 100644 app/assets/javascripts/harvests.js.coffee create mode 100644 app/controllers/harvests_controller.rb create mode 100644 app/helpers/harvests_helper.rb create mode 100644 app/models/harvest.rb create mode 100644 app/views/harvests/_form.html.haml create mode 100644 app/views/harvests/edit.html.haml create mode 100644 app/views/harvests/index.html.haml create mode 100644 app/views/harvests/new.html.haml create mode 100644 app/views/harvests/show.html.haml create mode 100644 db/migrate/20130917053547_create_harvests.rb create mode 100644 spec/controllers/harvests_controller_spec.rb create mode 100644 spec/factories/harvests.rb create mode 100644 spec/helpers/harvests_helper_spec.rb create mode 100644 spec/models/harvest_spec.rb create mode 100644 spec/requests/harvests_spec.rb create mode 100644 spec/routing/harvests_routing_spec.rb create mode 100644 spec/views/harvests/edit.html.haml_spec.rb create mode 100644 spec/views/harvests/index.html.haml_spec.rb create mode 100644 spec/views/harvests/new.html.haml_spec.rb create mode 100644 spec/views/harvests/show.html.haml_spec.rb diff --git a/app/assets/javascripts/harvests.js.coffee b/app/assets/javascripts/harvests.js.coffee new file mode 100644 index 000000000..761567942 --- /dev/null +++ b/app/assets/javascripts/harvests.js.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/ diff --git a/app/controllers/harvests_controller.rb b/app/controllers/harvests_controller.rb new file mode 100644 index 000000000..c99cf8ec7 --- /dev/null +++ b/app/controllers/harvests_controller.rb @@ -0,0 +1,83 @@ +class HarvestsController < ApplicationController + # GET /harvests + # GET /harvests.json + def index + @harvests = Harvest.all + + respond_to do |format| + format.html # index.html.erb + format.json { render json: @harvests } + end + end + + # GET /harvests/1 + # GET /harvests/1.json + def show + @harvest = Harvest.find(params[:id]) + + respond_to do |format| + format.html # show.html.erb + format.json { render json: @harvest } + end + end + + # GET /harvests/new + # GET /harvests/new.json + def new + @harvest = Harvest.new + + respond_to do |format| + format.html # new.html.erb + format.json { render json: @harvest } + end + end + + # GET /harvests/1/edit + def edit + @harvest = Harvest.find(params[:id]) + end + + # POST /harvests + # POST /harvests.json + def create + @harvest = Harvest.new(params[:harvest]) + + respond_to do |format| + if @harvest.save + format.html { redirect_to @harvest, notice: 'Harvest was successfully created.' } + format.json { render json: @harvest, status: :created, location: @harvest } + else + format.html { render action: "new" } + format.json { render json: @harvest.errors, status: :unprocessable_entity } + end + end + end + + # PUT /harvests/1 + # PUT /harvests/1.json + def update + @harvest = Harvest.find(params[:id]) + + respond_to do |format| + if @harvest.update_attributes(params[:harvest]) + format.html { redirect_to @harvest, notice: 'Harvest was successfully updated.' } + format.json { head :no_content } + else + format.html { render action: "edit" } + format.json { render json: @harvest.errors, status: :unprocessable_entity } + end + end + end + + # DELETE /harvests/1 + # DELETE /harvests/1.json + def destroy + @harvest = Harvest.find(params[:id]) + @harvest.destroy + + respond_to do |format| + format.html { redirect_to harvests_url } + format.json { head :no_content } + end + end +end diff --git a/app/helpers/harvests_helper.rb b/app/helpers/harvests_helper.rb new file mode 100644 index 000000000..4ef6343a1 --- /dev/null +++ b/app/helpers/harvests_helper.rb @@ -0,0 +1,2 @@ +module HarvestsHelper +end diff --git a/app/models/harvest.rb b/app/models/harvest.rb new file mode 100644 index 000000000..f0aa8a74d --- /dev/null +++ b/app/models/harvest.rb @@ -0,0 +1,3 @@ +class Harvest < ActiveRecord::Base + attr_accessible :crop_id, :harvested_at, :notes, :owner_id, :quantity, :units +end diff --git a/app/views/harvests/_form.html.haml b/app/views/harvests/_form.html.haml new file mode 100644 index 000000000..dbb8b4cdc --- /dev/null +++ b/app/views/harvests/_form.html.haml @@ -0,0 +1,28 @@ += form_for @harvest do |f| + - if @harvest.errors.any? + #error_explanation + %h2= "#{pluralize(@harvest.errors.count, "error")} prohibited this harvest from being saved:" + %ul + - @harvest.errors.full_messages.each do |msg| + %li= msg + + .field + = f.label :crop_id + = f.number_field :crop_id + .field + = f.label :owner_id + = f.number_field :owner_id + .field + = f.label :harvested_at + = f.date_select :harvested_at + .field + = f.label :quantity + = f.text_field :quantity + .field + = f.label :units + = f.text_field :units + .field + = f.label :notes + = f.text_area :notes + .actions + = f.submit 'Save' diff --git a/app/views/harvests/edit.html.haml b/app/views/harvests/edit.html.haml new file mode 100644 index 000000000..a5c973cd5 --- /dev/null +++ b/app/views/harvests/edit.html.haml @@ -0,0 +1,7 @@ +%h1 Editing harvest + += render 'form' + += link_to 'Show', @harvest +\| += link_to 'Back', harvests_path diff --git a/app/views/harvests/index.html.haml b/app/views/harvests/index.html.haml new file mode 100644 index 000000000..241c3bec5 --- /dev/null +++ b/app/views/harvests/index.html.haml @@ -0,0 +1,29 @@ +%h1 Listing harvests + +%table + %tr + %th Crop + %th Owner + %th Harvested at + %th Quantity + %th Units + %th Notes + %th + %th + %th + + - @harvests.each do |harvest| + %tr + %td= harvest.crop_id + %td= harvest.owner_id + %td= harvest.harvested_at + %td= harvest.quantity + %td= harvest.units + %td= harvest.notes + %td= link_to 'Show', harvest + %td= link_to 'Edit', edit_harvest_path(harvest) + %td= link_to 'Destroy', harvest, :method => :delete, :data => { :confirm => 'Are you sure?' } + +%br + += link_to 'New Harvest', new_harvest_path diff --git a/app/views/harvests/new.html.haml b/app/views/harvests/new.html.haml new file mode 100644 index 000000000..b37d95d92 --- /dev/null +++ b/app/views/harvests/new.html.haml @@ -0,0 +1,5 @@ +%h1 New harvest + += render 'form' + += link_to 'Back', harvests_path diff --git a/app/views/harvests/show.html.haml b/app/views/harvests/show.html.haml new file mode 100644 index 000000000..81d2a2ae3 --- /dev/null +++ b/app/views/harvests/show.html.haml @@ -0,0 +1,24 @@ +%p#notice= notice + +%p + %b Crop: + = @harvest.crop_id +%p + %b Owner: + = @harvest.owner_id +%p + %b Harvested at: + = @harvest.harvested_at +%p + %b Quantity: + = @harvest.quantity +%p + %b Units: + = @harvest.units +%p + %b Notes: + = @harvest.notes + += link_to 'Edit', edit_harvest_path(@harvest) +\| += link_to 'Back', harvests_path diff --git a/config/routes.rb b/config/routes.rb index 4ad09136e..f1f668afb 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,5 +1,8 @@ Growstuff::Application.routes.draw do + resources :harvests + + devise_for :members, :controllers => { :registrations => "registrations" } resources :members diff --git a/db/migrate/20130917053547_create_harvests.rb b/db/migrate/20130917053547_create_harvests.rb new file mode 100644 index 000000000..e7b7db6b4 --- /dev/null +++ b/db/migrate/20130917053547_create_harvests.rb @@ -0,0 +1,14 @@ +class CreateHarvests < ActiveRecord::Migration + def change + create_table :harvests do |t| + t.integer :crop_id, :null => false + t.integer :owner_id, :null => false + t.date :harvested_at + t.decimal :quantity + t.string :units + t.text :notes + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 7347be52c..6e4522731 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20130913015118) do +ActiveRecord::Schema.define(:version => 20130917053547) do create_table "account_types", :force => true do |t| t.string "name", :null => false @@ -87,6 +87,17 @@ ActiveRecord::Schema.define(:version => 20130913015118) do add_index "gardens", ["owner_id"], :name => "index_gardens_on_user_id" add_index "gardens", ["slug"], :name => "index_gardens_on_slug", :unique => true + create_table "harvests", :force => true do |t| + t.integer "crop_id", :null => false + t.integer "owner_id", :null => false + t.date "harvested_at" + t.decimal "quantity" + t.string "units" + t.text "notes" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + create_table "members", :force => true do |t| t.string "email", :default => "", :null => false t.string "encrypted_password", :default => "", :null => false diff --git a/spec/controllers/harvests_controller_spec.rb b/spec/controllers/harvests_controller_spec.rb new file mode 100644 index 000000000..13e05b107 --- /dev/null +++ b/spec/controllers/harvests_controller_spec.rb @@ -0,0 +1,164 @@ +require 'spec_helper' + +# This spec was generated by rspec-rails when you ran the scaffold generator. +# It demonstrates how one might use RSpec to specify 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. +# +# Compared to earlier versions of this generator, there is very limited use of +# stubs and message expectations in this spec. Stubs are only used when there +# is no simpler way to get a handle on the object needed for the example. +# Message expectations are only used when there is no simpler way to specify +# that an instance is receiving a specific message. + +describe HarvestsController do + + # This should return the minimal set of attributes required to create a valid + # Harvest. As you add validations to Harvest, be sure to + # update the return value of this method accordingly. + def valid_attributes + { "crop_id" => "1" } + end + + # This should return the minimal set of values that should be in the session + # in order to pass any filters (e.g. authentication) defined in + # HarvestsController. Be sure to keep this updated too. + def valid_session + {} + end + + describe "GET index" do + it "assigns all harvests as @harvests" do + harvest = Harvest.create! valid_attributes + get :index, {}, valid_session + assigns(:harvests).should eq([harvest]) + end + end + + describe "GET show" do + it "assigns the requested harvest as @harvest" do + harvest = Harvest.create! valid_attributes + get :show, {:id => harvest.to_param}, valid_session + assigns(:harvest).should eq(harvest) + end + end + + describe "GET new" do + it "assigns a new harvest as @harvest" do + get :new, {}, valid_session + assigns(:harvest).should be_a_new(Harvest) + end + end + + describe "GET edit" do + it "assigns the requested harvest as @harvest" do + harvest = Harvest.create! valid_attributes + get :edit, {:id => harvest.to_param}, valid_session + assigns(:harvest).should eq(harvest) + end + end + + describe "POST create" do + describe "with valid params" do + it "creates a new Harvest" do + expect { + post :create, {:harvest => valid_attributes}, valid_session + }.to change(Harvest, :count).by(1) + end + + it "assigns a newly created harvest as @harvest" do + post :create, {:harvest => valid_attributes}, valid_session + assigns(:harvest).should be_a(Harvest) + assigns(:harvest).should be_persisted + end + + it "redirects to the created harvest" do + post :create, {:harvest => valid_attributes}, valid_session + response.should redirect_to(Harvest.last) + end + end + + describe "with invalid params" do + it "assigns a newly created but unsaved harvest as @harvest" do + # Trigger the behavior that occurs when invalid params are submitted + Harvest.any_instance.stub(:save).and_return(false) + post :create, {:harvest => { "crop_id" => "invalid value" }}, valid_session + assigns(:harvest).should be_a_new(Harvest) + end + + it "re-renders the 'new' template" do + # Trigger the behavior that occurs when invalid params are submitted + Harvest.any_instance.stub(:save).and_return(false) + post :create, {:harvest => { "crop_id" => "invalid value" }}, valid_session + response.should render_template("new") + end + end + end + + describe "PUT update" do + describe "with valid params" do + it "updates the requested harvest" do + harvest = Harvest.create! valid_attributes + # Assuming there are no other harvests in the database, this + # specifies that the Harvest created on the previous line + # receives the :update_attributes message with whatever params are + # submitted in the request. + Harvest.any_instance.should_receive(:update_attributes).with({ "crop_id" => "1" }) + put :update, {:id => harvest.to_param, :harvest => { "crop_id" => "1" }}, valid_session + end + + it "assigns the requested harvest as @harvest" do + harvest = Harvest.create! valid_attributes + put :update, {:id => harvest.to_param, :harvest => valid_attributes}, valid_session + assigns(:harvest).should eq(harvest) + end + + it "redirects to the harvest" do + harvest = Harvest.create! valid_attributes + put :update, {:id => harvest.to_param, :harvest => valid_attributes}, valid_session + response.should redirect_to(harvest) + end + end + + describe "with invalid params" do + it "assigns the harvest as @harvest" do + harvest = Harvest.create! valid_attributes + # Trigger the behavior that occurs when invalid params are submitted + Harvest.any_instance.stub(:save).and_return(false) + put :update, {:id => harvest.to_param, :harvest => { "crop_id" => "invalid value" }}, valid_session + assigns(:harvest).should eq(harvest) + end + + it "re-renders the 'edit' template" do + harvest = Harvest.create! valid_attributes + # Trigger the behavior that occurs when invalid params are submitted + Harvest.any_instance.stub(:save).and_return(false) + put :update, {:id => harvest.to_param, :harvest => { "crop_id" => "invalid value" }}, valid_session + response.should render_template("edit") + end + end + end + + describe "DELETE destroy" do + it "destroys the requested harvest" do + harvest = Harvest.create! valid_attributes + expect { + delete :destroy, {:id => harvest.to_param}, valid_session + }.to change(Harvest, :count).by(-1) + end + + it "redirects to the harvests list" do + harvest = Harvest.create! valid_attributes + delete :destroy, {:id => harvest.to_param}, valid_session + response.should redirect_to(harvests_url) + end + end + +end diff --git a/spec/factories/harvests.rb b/spec/factories/harvests.rb new file mode 100644 index 000000000..00b59443d --- /dev/null +++ b/spec/factories/harvests.rb @@ -0,0 +1,12 @@ +# Read about factories at https://github.com/thoughtbot/factory_girl + +FactoryGirl.define do + factory :harvest do + crop_id 1 + owner_id 1 + harvested_at "2013-09-17" + quantity "9.99" + units "MyString" + notes "MyText" + end +end diff --git a/spec/helpers/harvests_helper_spec.rb b/spec/helpers/harvests_helper_spec.rb new file mode 100644 index 000000000..eb5690c3d --- /dev/null +++ b/spec/helpers/harvests_helper_spec.rb @@ -0,0 +1,15 @@ +require 'spec_helper' + +# Specs in this file have access to a helper object that includes +# the HarvestsHelper. For example: +# +# describe HarvestsHelper do +# describe "string concat" do +# it "concats two strings with spaces" do +# helper.concat_strings("this","that").should == "this that" +# end +# end +# end +describe HarvestsHelper do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/models/harvest_spec.rb b/spec/models/harvest_spec.rb new file mode 100644 index 000000000..e8696f1ef --- /dev/null +++ b/spec/models/harvest_spec.rb @@ -0,0 +1,5 @@ +require 'spec_helper' + +describe Harvest do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/requests/harvests_spec.rb b/spec/requests/harvests_spec.rb new file mode 100644 index 000000000..edb408b0b --- /dev/null +++ b/spec/requests/harvests_spec.rb @@ -0,0 +1,11 @@ +require 'spec_helper' + +describe "Harvests" do + describe "GET /harvests" do + it "works! (now write some real specs)" do + # Run the generator again with the --webrat flag if you want to use webrat methods/matchers + get harvests_path + response.status.should be(200) + end + end +end diff --git a/spec/routing/harvests_routing_spec.rb b/spec/routing/harvests_routing_spec.rb new file mode 100644 index 000000000..66ab7151e --- /dev/null +++ b/spec/routing/harvests_routing_spec.rb @@ -0,0 +1,35 @@ +require "spec_helper" + +describe HarvestsController do + describe "routing" do + + it "routes to #index" do + get("/harvests").should route_to("harvests#index") + end + + it "routes to #new" do + get("/harvests/new").should route_to("harvests#new") + end + + it "routes to #show" do + get("/harvests/1").should route_to("harvests#show", :id => "1") + end + + it "routes to #edit" do + get("/harvests/1/edit").should route_to("harvests#edit", :id => "1") + end + + it "routes to #create" do + post("/harvests").should route_to("harvests#create") + end + + it "routes to #update" do + put("/harvests/1").should route_to("harvests#update", :id => "1") + end + + it "routes to #destroy" do + delete("/harvests/1").should route_to("harvests#destroy", :id => "1") + end + + end +end diff --git a/spec/views/harvests/edit.html.haml_spec.rb b/spec/views/harvests/edit.html.haml_spec.rb new file mode 100644 index 000000000..904b526e1 --- /dev/null +++ b/spec/views/harvests/edit.html.haml_spec.rb @@ -0,0 +1,26 @@ +require 'spec_helper' + +describe "harvests/edit" do + before(:each) do + @harvest = assign(:harvest, stub_model(Harvest, + :crop_id => 1, + :owner_id => 1, + :quantity => "9.99", + :units => "MyString", + :notes => "MyText" + )) + end + + it "renders the edit harvest form" do + render + + # Run the generator again with the --webrat flag if you want to use webrat matchers + assert_select "form", :action => harvests_path(@harvest), :method => "post" do + assert_select "input#harvest_crop_id", :name => "harvest[crop_id]" + assert_select "input#harvest_owner_id", :name => "harvest[owner_id]" + assert_select "input#harvest_quantity", :name => "harvest[quantity]" + assert_select "input#harvest_units", :name => "harvest[units]" + assert_select "textarea#harvest_notes", :name => "harvest[notes]" + end + end +end diff --git a/spec/views/harvests/index.html.haml_spec.rb b/spec/views/harvests/index.html.haml_spec.rb new file mode 100644 index 000000000..aa4403974 --- /dev/null +++ b/spec/views/harvests/index.html.haml_spec.rb @@ -0,0 +1,32 @@ +require 'spec_helper' + +describe "harvests/index" do + before(:each) do + assign(:harvests, [ + stub_model(Harvest, + :crop_id => 1, + :owner_id => 2, + :quantity => "9.99", + :units => "Units", + :notes => "MyText" + ), + stub_model(Harvest, + :crop_id => 1, + :owner_id => 2, + :quantity => "9.99", + :units => "Units", + :notes => "MyText" + ) + ]) + end + + it "renders a list of harvests" do + render + # Run the generator again with the --webrat flag if you want to use webrat matchers + assert_select "tr>td", :text => 1.to_s, :count => 2 + assert_select "tr>td", :text => 2.to_s, :count => 2 + assert_select "tr>td", :text => "9.99".to_s, :count => 2 + assert_select "tr>td", :text => "Units".to_s, :count => 2 + assert_select "tr>td", :text => "MyText".to_s, :count => 2 + end +end diff --git a/spec/views/harvests/new.html.haml_spec.rb b/spec/views/harvests/new.html.haml_spec.rb new file mode 100644 index 000000000..3faa2e924 --- /dev/null +++ b/spec/views/harvests/new.html.haml_spec.rb @@ -0,0 +1,26 @@ +require 'spec_helper' + +describe "harvests/new" do + before(:each) do + assign(:harvest, stub_model(Harvest, + :crop_id => 1, + :owner_id => 1, + :quantity => "9.99", + :units => "MyString", + :notes => "MyText" + ).as_new_record) + end + + it "renders new harvest form" do + render + + # Run the generator again with the --webrat flag if you want to use webrat matchers + assert_select "form", :action => harvests_path, :method => "post" do + assert_select "input#harvest_crop_id", :name => "harvest[crop_id]" + assert_select "input#harvest_owner_id", :name => "harvest[owner_id]" + assert_select "input#harvest_quantity", :name => "harvest[quantity]" + assert_select "input#harvest_units", :name => "harvest[units]" + assert_select "textarea#harvest_notes", :name => "harvest[notes]" + end + end +end diff --git a/spec/views/harvests/show.html.haml_spec.rb b/spec/views/harvests/show.html.haml_spec.rb new file mode 100644 index 000000000..f726d0a8e --- /dev/null +++ b/spec/views/harvests/show.html.haml_spec.rb @@ -0,0 +1,23 @@ +require 'spec_helper' + +describe "harvests/show" do + before(:each) do + @harvest = assign(:harvest, stub_model(Harvest, + :crop_id => 1, + :owner_id => 2, + :quantity => "9.99", + :units => "Units", + :notes => "MyText" + )) + end + + it "renders attributes in

" do + render + # Run the generator again with the --webrat flag if you want to use webrat matchers + rendered.should match(/1/) + rendered.should match(/2/) + rendered.should match(/9.99/) + rendered.should match(/Units/) + rendered.should match(/MyText/) + end +end From 2196bc837345d768c4f8b7ae3b1a9ecfa4382255 Mon Sep 17 00:00:00 2001 From: Skud Date: Tue, 17 Sep 2013 15:50:25 +1000 Subject: [PATCH 04/28] Added associations between harvests, crops, and members --- app/models/crop.rb | 1 + app/models/harvest.rb | 4 ++++ app/models/member.rb | 1 + spec/factories/harvests.rb | 8 ++++---- spec/models/crop_spec.rb | 8 ++++++++ spec/models/harvest_spec.rb | 12 +++++++++++- spec/models/member_spec.rb | 8 ++++++++ 7 files changed, 37 insertions(+), 5 deletions(-) diff --git a/app/models/crop.rb b/app/models/crop.rb index 8bae75bc4..e8d332220 100644 --- a/app/models/crop.rb +++ b/app/models/crop.rb @@ -7,6 +7,7 @@ class Crop < ActiveRecord::Base has_many :plantings has_many :photos, :through => :plantings has_many :seeds + has_many :harvests belongs_to :creator, :class_name => 'Member' belongs_to :parent, :class_name => 'Crop' diff --git a/app/models/harvest.rb b/app/models/harvest.rb index f0aa8a74d..f987c330f 100644 --- a/app/models/harvest.rb +++ b/app/models/harvest.rb @@ -1,3 +1,7 @@ class Harvest < ActiveRecord::Base attr_accessible :crop_id, :harvested_at, :notes, :owner_id, :quantity, :units + + belongs_to :crop + belongs_to :owner, :class_name => 'Member' + end diff --git a/app/models/member.rb b/app/models/member.rb index 67eaf9976..b39d01ea0 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -10,6 +10,7 @@ class Member < ActiveRecord::Base has_many :plantings, :foreign_key => 'owner_id' has_many :seeds, :foreign_key => 'owner_id' + has_many :harvests, :foreign_key => 'owner_id' has_and_belongs_to_many :roles diff --git a/spec/factories/harvests.rb b/spec/factories/harvests.rb index 00b59443d..d36e9082f 100644 --- a/spec/factories/harvests.rb +++ b/spec/factories/harvests.rb @@ -2,11 +2,11 @@ FactoryGirl.define do factory :harvest do - crop_id 1 - owner_id 1 + crop + owner harvested_at "2013-09-17" quantity "9.99" - units "MyString" - notes "MyText" + units "kg" + notes "A lovely harvest" end end diff --git a/spec/models/crop_spec.rb b/spec/models/crop_spec.rb index e872d2ecd..1e0c3c4c1 100644 --- a/spec/models/crop_spec.rb +++ b/spec/models/crop_spec.rb @@ -235,4 +235,12 @@ describe Crop do end + context "harvests" do + it "has harvests" do + crop = FactoryGirl.create(:crop) + harvest = FactoryGirl.create(:harvest, :crop => crop) + crop.harvests.should eq [harvest] + end + end + end diff --git a/spec/models/harvest_spec.rb b/spec/models/harvest_spec.rb index e8696f1ef..7b3872161 100644 --- a/spec/models/harvest_spec.rb +++ b/spec/models/harvest_spec.rb @@ -1,5 +1,15 @@ require 'spec_helper' describe Harvest do - pending "add some examples to (or delete) #{__FILE__}" + + it "has an owner" do + harvest = FactoryGirl.create(:harvest) + harvest.owner.should be_an_instance_of Member + end + + it "has a crop" do + harvest = FactoryGirl.create(:harvest) + harvest.crop.should be_an_instance_of Crop + end + end diff --git a/spec/models/member_spec.rb b/spec/models/member_spec.rb index 349fd2ce5..49b66ef71 100644 --- a/spec/models/member_spec.rb +++ b/spec/models/member_spec.rb @@ -373,4 +373,12 @@ describe 'member' do end end + context 'harvests' do + it 'has harvests' do + member = FactoryGirl.create(:member) + harvest = FactoryGirl.create(:harvest, :owner => member) + member.harvests.should eq [harvest] + end + end + end From 67b88e8e18d83deda74f7bc3ce98f6ace7c5e2fd Mon Sep 17 00:00:00 2001 From: Skud Date: Tue, 17 Sep 2013 15:53:51 +1000 Subject: [PATCH 05/28] set cancan abilities for harvests --- app/controllers/harvests_controller.rb | 3 +++ app/models/ability.rb | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/app/controllers/harvests_controller.rb b/app/controllers/harvests_controller.rb index c99cf8ec7..eb649ecc4 100644 --- a/app/controllers/harvests_controller.rb +++ b/app/controllers/harvests_controller.rb @@ -1,4 +1,7 @@ class HarvestsController < ApplicationController + + load_and_authorize_resource + # GET /harvests # GET /harvests.json def index diff --git a/app/models/ability.rb b/app/models/ability.rb index b5fafd8ec..c13a80006 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -64,6 +64,10 @@ class Ability can :update, Planting, :garden => { :owner_id => member.id } can :destroy, Planting, :garden => { :owner_id => member.id } + can :create, Harvest + can :update, Harvest, :owner_id => member.id + can :destroy, Harvest, :owner_id => member.id + can :create, Photo can :update, Photo, :owner_id => member.id can :destroy, Photo, :owner_id => member.id From ccb0e42c95b1f8f3c771ceb3a0608b04b2d06479 Mon Sep 17 00:00:00 2001 From: Skud Date: Tue, 17 Sep 2013 16:08:41 +1000 Subject: [PATCH 06/28] Prettified harvest form Also renamed "notes" to "description" in database --- app/controllers/harvests_controller.rb | 7 ++- app/models/harvest.rb | 2 +- app/views/harvests/_form.html.haml | 47 ++++++++++--------- app/views/harvests/index.html.haml | 2 +- app/views/harvests/new.html.haml | 2 - app/views/harvests/show.html.haml | 6 +-- ...257_change_harvest_notes_to_description.rb | 5 ++ db/schema.rb | 4 +- 8 files changed, 42 insertions(+), 33 deletions(-) create mode 100644 db/migrate/20130917060257_change_harvest_notes_to_description.rb diff --git a/app/controllers/harvests_controller.rb b/app/controllers/harvests_controller.rb index eb649ecc4..171c47ec3 100644 --- a/app/controllers/harvests_controller.rb +++ b/app/controllers/harvests_controller.rb @@ -27,7 +27,10 @@ class HarvestsController < ApplicationController # GET /harvests/new # GET /harvests/new.json def new - @harvest = Harvest.new + @harvest = Harvest.new('harvested_at' => Date.today) + + # using find_by_id here because it returns nil, unlike find + @crop = Crop.find_by_id(params[:crop_id]) || Crop.new respond_to do |format| format.html # new.html.erb @@ -43,6 +46,8 @@ class HarvestsController < ApplicationController # POST /harvests # POST /harvests.json def create + params[:harvest][:owner_id] = current_member.id + params[:harvested_at] = parse_date(params[:harvested_at]) @harvest = Harvest.new(params[:harvest]) respond_to do |format| diff --git a/app/models/harvest.rb b/app/models/harvest.rb index f987c330f..48e6ede26 100644 --- a/app/models/harvest.rb +++ b/app/models/harvest.rb @@ -1,5 +1,5 @@ class Harvest < ActiveRecord::Base - attr_accessible :crop_id, :harvested_at, :notes, :owner_id, :quantity, :units + attr_accessible :crop_id, :harvested_at, :description, :owner_id, :quantity, :units belongs_to :crop belongs_to :owner, :class_name => 'Member' diff --git a/app/views/harvests/_form.html.haml b/app/views/harvests/_form.html.haml index dbb8b4cdc..31f90bd30 100644 --- a/app/views/harvests/_form.html.haml +++ b/app/views/harvests/_form.html.haml @@ -1,4 +1,4 @@ -= form_for @harvest do |f| += form_for(@harvest, :html => {:class => "form-horizontal"}) do |f| - if @harvest.errors.any? #error_explanation %h2= "#{pluralize(@harvest.errors.count, "error")} prohibited this harvest from being saved:" @@ -6,23 +6,28 @@ - @harvest.errors.full_messages.each do |msg| %li= msg - .field - = f.label :crop_id - = f.number_field :crop_id - .field - = f.label :owner_id - = f.number_field :owner_id - .field - = f.label :harvested_at - = f.date_select :harvested_at - .field - = f.label :quantity - = f.text_field :quantity - .field - = f.label :units - = f.text_field :units - .field - = f.label :notes - = f.text_area :notes - .actions - = f.submit 'Save' + .control-group + = f.label 'What did you harvest?', :class => 'control-label' + .controls + = collection_select(:harvest, :crop_id, Crop.all, :id, :system_name, :selected => @harvest.crop_id || @crop.id) + %span.help-inline + Can't find what you're looking for? + = link_to "Request new crops.", Growstuff::Application.config.new_crops_request_link + + .control-group + = f.label 'When?', :class => 'control-label' + .controls= f.text_field :harvested_at, :value => @harvest.harvested_at ? @harvest.harvested_at.to_s(:ymd) : '', :class => 'add-datepicker' + + .control-group + = f.label 'How many?', :class => 'control-label' + .controls + = f.number_field :quantity, :class => 'input-small' + = f.text_field :units, :class => 'input-small' + + .control-group + = f.label 'Notes', :class => 'control-label' + .controls= f.text_area :description, :rows => 6 + + .form-actions + = f.submit 'Save', :class => 'btn btn-primary' + diff --git a/app/views/harvests/index.html.haml b/app/views/harvests/index.html.haml index 241c3bec5..427fba99e 100644 --- a/app/views/harvests/index.html.haml +++ b/app/views/harvests/index.html.haml @@ -19,7 +19,7 @@ %td= harvest.harvested_at %td= harvest.quantity %td= harvest.units - %td= harvest.notes + %td= harvest.description %td= link_to 'Show', harvest %td= link_to 'Edit', edit_harvest_path(harvest) %td= link_to 'Destroy', harvest, :method => :delete, :data => { :confirm => 'Are you sure?' } diff --git a/app/views/harvests/new.html.haml b/app/views/harvests/new.html.haml index b37d95d92..63a90e303 100644 --- a/app/views/harvests/new.html.haml +++ b/app/views/harvests/new.html.haml @@ -1,5 +1,3 @@ %h1 New harvest = render 'form' - -= link_to 'Back', harvests_path diff --git a/app/views/harvests/show.html.haml b/app/views/harvests/show.html.haml index 81d2a2ae3..e20baf91d 100644 --- a/app/views/harvests/show.html.haml +++ b/app/views/harvests/show.html.haml @@ -17,8 +17,4 @@ = @harvest.units %p %b Notes: - = @harvest.notes - -= link_to 'Edit', edit_harvest_path(@harvest) -\| -= link_to 'Back', harvests_path + = @harvest.description diff --git a/db/migrate/20130917060257_change_harvest_notes_to_description.rb b/db/migrate/20130917060257_change_harvest_notes_to_description.rb new file mode 100644 index 000000000..bac3167cf --- /dev/null +++ b/db/migrate/20130917060257_change_harvest_notes_to_description.rb @@ -0,0 +1,5 @@ +class ChangeHarvestNotesToDescription < ActiveRecord::Migration + def change + rename_column :harvests, :notes, :description + end +end diff --git a/db/schema.rb b/db/schema.rb index 6e4522731..19237834b 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20130917053547) do +ActiveRecord::Schema.define(:version => 20130917060257) do create_table "account_types", :force => true do |t| t.string "name", :null => false @@ -93,7 +93,7 @@ ActiveRecord::Schema.define(:version => 20130917053547) do t.date "harvested_at" t.decimal "quantity" t.string "units" - t.text "notes" + t.text "description" t.datetime "created_at", :null => false t.datetime "updated_at", :null => false end From ebf60346595196cf6a06860465f3e7432e61f78b Mon Sep 17 00:00:00 2001 From: Skud Date: Tue, 17 Sep 2013 17:09:17 +1000 Subject: [PATCH 07/28] Prettified all the harvest views --- app/controllers/harvests_controller.rb | 7 +- app/views/harvests/edit.html.haml | 2 +- app/views/harvests/index.html.haml | 69 +++++++++++++------- app/views/harvests/new.html.haml | 2 +- app/views/harvests/show.html.haml | 50 ++++++++------ app/views/layouts/_header.html.haml | 1 + config/routes.rb | 6 +- spec/controllers/harvests_controller_spec.rb | 67 +++++++------------ spec/factories/harvests.rb | 2 +- spec/helpers/harvests_helper_spec.rb | 15 ----- spec/views/harvests/edit.html.haml_spec.rb | 21 ++---- spec/views/harvests/index.html.haml_spec.rb | 46 ++++++------- spec/views/harvests/new.html.haml_spec.rb | 17 ++--- spec/views/harvests/show.html.haml_spec.rb | 24 +++---- 14 files changed, 154 insertions(+), 175 deletions(-) delete mode 100644 spec/helpers/harvests_helper_spec.rb diff --git a/app/controllers/harvests_controller.rb b/app/controllers/harvests_controller.rb index 171c47ec3..1c529df87 100644 --- a/app/controllers/harvests_controller.rb +++ b/app/controllers/harvests_controller.rb @@ -5,7 +5,12 @@ class HarvestsController < ApplicationController # GET /harvests # GET /harvests.json def index - @harvests = Harvest.all + @owner = Member.find_by_slug(params[:owner]) + if @owner + @harvests = @owner.harvests.includes(:owner, :crop).paginate(:page => params[:page]) + else + @harvests = Harvest.includes(:owner, :crop).paginate(:page => params[:page]) + end respond_to do |format| format.html # index.html.erb diff --git a/app/views/harvests/edit.html.haml b/app/views/harvests/edit.html.haml index a5c973cd5..8cbe1e62c 100644 --- a/app/views/harvests/edit.html.haml +++ b/app/views/harvests/edit.html.haml @@ -1,4 +1,4 @@ -%h1 Editing harvest +- content_for :title, "Editing harvest" = render 'form' diff --git a/app/views/harvests/index.html.haml b/app/views/harvests/index.html.haml index 427fba99e..e0b96b981 100644 --- a/app/views/harvests/index.html.haml +++ b/app/views/harvests/index.html.haml @@ -1,29 +1,50 @@ -%h1 Listing harvests +- content_for :title, @owner ? "#{@owner}'s harvests" : "Everyone's harvests" -%table - %tr - %th Crop - %th Owner - %th Harvested at - %th Quantity - %th Units - %th Notes - %th - %th - %th +%p + #{Growstuff::Application.config.site_name} helps you track what you're + harvesting from your home garden and see how productive it is. - - @harvests.each do |harvest| +%p + - if can? :create, Harvest + - if @owner + %p + - if @owner == current_member + = link_to 'Add harvest', new_harvest_path, :class => 'btn btn-primary' + = link_to "View everyone's harvests", harvests_path, :class => 'btn' + - else # everyone's harvests + = link_to 'Add harvest', new_harvest_path, :class => 'btn btn-primary' + - if current_member + = link_to 'View your harvests', harvests_by_owner_path(:owner => current_member.slug), :class => 'btn' + - else + = render :partial => 'shared/signin_signup', :locals => { :to => 'track your harvests' } + +%div.pagination + = page_entries_info @harvests, :model => "harvests" + = will_paginate @harvests + +- if @harvests.length > 0 + + %table.table.table-striped %tr - %td= harvest.crop_id - %td= harvest.owner_id - %td= harvest.harvested_at - %td= harvest.quantity - %td= harvest.units - %td= harvest.description - %td= link_to 'Show', harvest - %td= link_to 'Edit', edit_harvest_path(harvest) - %td= link_to 'Destroy', harvest, :method => :delete, :data => { :confirm => 'Are you sure?' } + - unless @owner + %th Owner + %th Crop + %th Quantity + %th Description + %th -%br + - @harvests.each do |harvest| + %tr + - unless @owner + %td= link_to harvest.owner.login_name, harvest.owner + %td= link_to harvest.crop.system_name, harvest.crop + %td + - if harvest.quantity + = harvest.quantity + = harvest.units + %td= harvest.description + %td= link_to 'Details', harvest, :class => 'btn btn-mini' -= link_to 'New Harvest', new_harvest_path + %div.pagination + = page_entries_info @harvests, :model => "harvests" + = will_paginate @harvests diff --git a/app/views/harvests/new.html.haml b/app/views/harvests/new.html.haml index 63a90e303..5b5004622 100644 --- a/app/views/harvests/new.html.haml +++ b/app/views/harvests/new.html.haml @@ -1,3 +1,3 @@ -%h1 New harvest +- content_for :title, "New Harvest" = render 'form' diff --git a/app/views/harvests/show.html.haml b/app/views/harvests/show.html.haml index e20baf91d..7f866858b 100644 --- a/app/views/harvests/show.html.haml +++ b/app/views/harvests/show.html.haml @@ -1,20 +1,32 @@ -%p#notice= notice +=content_for :title, "#{@harvest.crop} harvested by #{@harvest.owner}" -%p - %b Crop: - = @harvest.crop_id -%p - %b Owner: - = @harvest.owner_id -%p - %b Harvested at: - = @harvest.harvested_at -%p - %b Quantity: - = @harvest.quantity -%p - %b Units: - = @harvest.units -%p - %b Notes: - = @harvest.description +.row-fluid + .span6 + %p + %b Harvested: + = @harvest.harvested_at ? @harvest.harvested_at : "not specified" + %p + %b Quantity: + - if ! @harvest.quantity.blank? + = @harvest.quantity + = @harvest.units + - else + not specified + + - if can? :edit, @harvest or can? :destroy, @harvest + %p + - if can? :edit, @harvest + =link_to 'Edit', edit_harvest_path(@harvest), :class => 'btn btn-mini' + - if can? :destroy, @harvest + =link_to 'Delete', @harvest, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-mini' + + .span6 + = render :partial => "crops/index_card", :locals => { :crop => @harvest.crop} + +%h2 Notes + +:markdown + #{ @harvest.description != "" ? @harvest.description : "No description given." } + +- if can? :edit, @harvest + = link_to 'Edit', edit_harvest_path(@harvest), :class => 'btn btn-mini' diff --git a/app/views/layouts/_header.html.haml b/app/views/layouts/_header.html.haml index 3e2b59f5d..a00e2da83 100644 --- a/app/views/layouts/_header.html.haml +++ b/app/views/layouts/_header.html.haml @@ -34,6 +34,7 @@ %li= link_to "Profile", member_path(current_member) %li= link_to "Gardens", gardens_by_owner_path(:owner => current_member.slug) %li= link_to "Plantings", plantings_by_owner_path(:owner => current_member.slug) + %li= link_to "Harvests", harvests_by_owner_path(:owner => current_member.slug) %li= link_to "Seeds", seeds_by_owner_path(:owner => current_member.slug) %li= link_to "Posts", posts_by_author_path(:author => current_member.slug) %li= link_to "Account", orders_path diff --git a/config/routes.rb b/config/routes.rb index f1f668afb..1be11c8a5 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,8 +1,5 @@ Growstuff::Application.routes.draw do - resources :harvests - - devise_for :members, :controllers => { :registrations => "registrations" } resources :members @@ -19,6 +16,9 @@ Growstuff::Application.routes.draw do resources :seeds match '/seeds/owner/:owner' => 'seeds#index', :as => 'seeds_by_owner' + resources :harvests + match '/harvests/owner/:owner' => 'harvests#index', :as => 'harvests_by_owner' + resources :posts match '/posts/author/:author' => 'posts#index', :as => 'posts_by_author' diff --git a/spec/controllers/harvests_controller_spec.rb b/spec/controllers/harvests_controller_spec.rb index 13e05b107..f2ecb8e32 100644 --- a/spec/controllers/harvests_controller_spec.rb +++ b/spec/controllers/harvests_controller_spec.rb @@ -1,43 +1,20 @@ require 'spec_helper' -# This spec was generated by rspec-rails when you ran the scaffold generator. -# It demonstrates how one might use RSpec to specify 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. -# -# Compared to earlier versions of this generator, there is very limited use of -# stubs and message expectations in this spec. Stubs are only used when there -# is no simpler way to get a handle on the object needed for the example. -# Message expectations are only used when there is no simpler way to specify -# that an instance is receiving a specific message. - describe HarvestsController do - # This should return the minimal set of attributes required to create a valid - # Harvest. As you add validations to Harvest, be sure to - # update the return value of this method accordingly. - def valid_attributes - { "crop_id" => "1" } - end + login_member - # This should return the minimal set of values that should be in the session - # in order to pass any filters (e.g. authentication) defined in - # HarvestsController. Be sure to keep this updated too. - def valid_session - {} + def valid_attributes + { + :owner_id => subject.current_member.id, + :crop_id => FactoryGirl.create(:crop).id + } end describe "GET index" do it "assigns all harvests as @harvests" do harvest = Harvest.create! valid_attributes - get :index, {}, valid_session + get :index, {} assigns(:harvests).should eq([harvest]) end end @@ -45,14 +22,14 @@ describe HarvestsController do describe "GET show" do it "assigns the requested harvest as @harvest" do harvest = Harvest.create! valid_attributes - get :show, {:id => harvest.to_param}, valid_session + get :show, {:id => harvest.to_param} assigns(:harvest).should eq(harvest) end end describe "GET new" do it "assigns a new harvest as @harvest" do - get :new, {}, valid_session + get :new, {} assigns(:harvest).should be_a_new(Harvest) end end @@ -60,7 +37,7 @@ describe HarvestsController do describe "GET edit" do it "assigns the requested harvest as @harvest" do harvest = Harvest.create! valid_attributes - get :edit, {:id => harvest.to_param}, valid_session + get :edit, {:id => harvest.to_param} assigns(:harvest).should eq(harvest) end end @@ -69,18 +46,18 @@ describe HarvestsController do describe "with valid params" do it "creates a new Harvest" do expect { - post :create, {:harvest => valid_attributes}, valid_session + post :create, {:harvest => valid_attributes} }.to change(Harvest, :count).by(1) end it "assigns a newly created harvest as @harvest" do - post :create, {:harvest => valid_attributes}, valid_session + post :create, {:harvest => valid_attributes} assigns(:harvest).should be_a(Harvest) assigns(:harvest).should be_persisted end it "redirects to the created harvest" do - post :create, {:harvest => valid_attributes}, valid_session + post :create, {:harvest => valid_attributes} response.should redirect_to(Harvest.last) end end @@ -89,14 +66,14 @@ describe HarvestsController do it "assigns a newly created but unsaved harvest as @harvest" do # Trigger the behavior that occurs when invalid params are submitted Harvest.any_instance.stub(:save).and_return(false) - post :create, {:harvest => { "crop_id" => "invalid value" }}, valid_session + post :create, {:harvest => { "crop_id" => "invalid value" }} assigns(:harvest).should be_a_new(Harvest) end it "re-renders the 'new' template" do # Trigger the behavior that occurs when invalid params are submitted Harvest.any_instance.stub(:save).and_return(false) - post :create, {:harvest => { "crop_id" => "invalid value" }}, valid_session + post :create, {:harvest => { "crop_id" => "invalid value" }} response.should render_template("new") end end @@ -111,18 +88,18 @@ describe HarvestsController do # receives the :update_attributes message with whatever params are # submitted in the request. Harvest.any_instance.should_receive(:update_attributes).with({ "crop_id" => "1" }) - put :update, {:id => harvest.to_param, :harvest => { "crop_id" => "1" }}, valid_session + put :update, {:id => harvest.to_param, :harvest => { "crop_id" => "1" }} end it "assigns the requested harvest as @harvest" do harvest = Harvest.create! valid_attributes - put :update, {:id => harvest.to_param, :harvest => valid_attributes}, valid_session + put :update, {:id => harvest.to_param, :harvest => valid_attributes} assigns(:harvest).should eq(harvest) end it "redirects to the harvest" do harvest = Harvest.create! valid_attributes - put :update, {:id => harvest.to_param, :harvest => valid_attributes}, valid_session + put :update, {:id => harvest.to_param, :harvest => valid_attributes} response.should redirect_to(harvest) end end @@ -132,7 +109,7 @@ describe HarvestsController do harvest = Harvest.create! valid_attributes # Trigger the behavior that occurs when invalid params are submitted Harvest.any_instance.stub(:save).and_return(false) - put :update, {:id => harvest.to_param, :harvest => { "crop_id" => "invalid value" }}, valid_session + put :update, {:id => harvest.to_param, :harvest => { "crop_id" => "invalid value" }} assigns(:harvest).should eq(harvest) end @@ -140,7 +117,7 @@ describe HarvestsController do harvest = Harvest.create! valid_attributes # Trigger the behavior that occurs when invalid params are submitted Harvest.any_instance.stub(:save).and_return(false) - put :update, {:id => harvest.to_param, :harvest => { "crop_id" => "invalid value" }}, valid_session + put :update, {:id => harvest.to_param, :harvest => { "crop_id" => "invalid value" }} response.should render_template("edit") end end @@ -150,13 +127,13 @@ describe HarvestsController do it "destroys the requested harvest" do harvest = Harvest.create! valid_attributes expect { - delete :destroy, {:id => harvest.to_param}, valid_session + delete :destroy, {:id => harvest.to_param} }.to change(Harvest, :count).by(-1) end it "redirects to the harvests list" do harvest = Harvest.create! valid_attributes - delete :destroy, {:id => harvest.to_param}, valid_session + delete :destroy, {:id => harvest.to_param} response.should redirect_to(harvests_url) end end diff --git a/spec/factories/harvests.rb b/spec/factories/harvests.rb index d36e9082f..6b9e336e9 100644 --- a/spec/factories/harvests.rb +++ b/spec/factories/harvests.rb @@ -7,6 +7,6 @@ FactoryGirl.define do harvested_at "2013-09-17" quantity "9.99" units "kg" - notes "A lovely harvest" + description "A lovely harvest" end end diff --git a/spec/helpers/harvests_helper_spec.rb b/spec/helpers/harvests_helper_spec.rb deleted file mode 100644 index eb5690c3d..000000000 --- a/spec/helpers/harvests_helper_spec.rb +++ /dev/null @@ -1,15 +0,0 @@ -require 'spec_helper' - -# Specs in this file have access to a helper object that includes -# the HarvestsHelper. For example: -# -# describe HarvestsHelper do -# describe "string concat" do -# it "concats two strings with spaces" do -# helper.concat_strings("this","that").should == "this that" -# end -# end -# end -describe HarvestsHelper do - pending "add some examples to (or delete) #{__FILE__}" -end diff --git a/spec/views/harvests/edit.html.haml_spec.rb b/spec/views/harvests/edit.html.haml_spec.rb index 904b526e1..dd26b7926 100644 --- a/spec/views/harvests/edit.html.haml_spec.rb +++ b/spec/views/harvests/edit.html.haml_spec.rb @@ -2,25 +2,16 @@ require 'spec_helper' describe "harvests/edit" do before(:each) do - @harvest = assign(:harvest, stub_model(Harvest, - :crop_id => 1, - :owner_id => 1, - :quantity => "9.99", - :units => "MyString", - :notes => "MyText" - )) + assign(:harvest, FactoryGirl.create(:harvest)) + render end - it "renders the edit harvest form" do - render - - # Run the generator again with the --webrat flag if you want to use webrat matchers - assert_select "form", :action => harvests_path(@harvest), :method => "post" do - assert_select "input#harvest_crop_id", :name => "harvest[crop_id]" - assert_select "input#harvest_owner_id", :name => "harvest[owner_id]" + it "renders new harvest form" do + assert_select "form", :action => harvests_path, :method => "post" do + assert_select "select#harvest_crop_id", :name => "harvest[crop_id]" assert_select "input#harvest_quantity", :name => "harvest[quantity]" assert_select "input#harvest_units", :name => "harvest[units]" - assert_select "textarea#harvest_notes", :name => "harvest[notes]" + assert_select "textarea#harvest_description", :name => "harvest[description]" end end end diff --git a/spec/views/harvests/index.html.haml_spec.rb b/spec/views/harvests/index.html.haml_spec.rb index aa4403974..9a5712b14 100644 --- a/spec/views/harvests/index.html.haml_spec.rb +++ b/spec/views/harvests/index.html.haml_spec.rb @@ -2,31 +2,33 @@ require 'spec_helper' describe "harvests/index" do before(:each) do - assign(:harvests, [ - stub_model(Harvest, - :crop_id => 1, - :owner_id => 2, - :quantity => "9.99", - :units => "Units", - :notes => "MyText" - ), - stub_model(Harvest, - :crop_id => 1, - :owner_id => 2, - :quantity => "9.99", - :units => "Units", - :notes => "MyText" - ) - ]) + controller.stub(:current_user) { nil } + @member = FactoryGirl.create(:member) + @tomato = FactoryGirl.create(:tomato) + @maize = FactoryGirl.create(:maize) + page = 1 + per_page = 2 + total_entries = 2 + harvests = WillPaginate::Collection.create(page, per_page, total_entries) do |pager| + pager.replace([ + FactoryGirl.create(:harvest, + :crop => @tomato, + :owner => @member + ), + FactoryGirl.create(:harvest, + :crop => @maize, + :owner => @member + ) + ]) + end + assign(:harvests, harvests) + render end it "renders a list of harvests" do render - # Run the generator again with the --webrat flag if you want to use webrat matchers - assert_select "tr>td", :text => 1.to_s, :count => 2 - assert_select "tr>td", :text => 2.to_s, :count => 2 - assert_select "tr>td", :text => "9.99".to_s, :count => 2 - assert_select "tr>td", :text => "Units".to_s, :count => 2 - assert_select "tr>td", :text => "MyText".to_s, :count => 2 + assert_select "tr>td", :text => @member.login_name + assert_select "tr>td", :text => @tomato.system_name + assert_select "tr>td", :text => @maize.system_name end end diff --git a/spec/views/harvests/new.html.haml_spec.rb b/spec/views/harvests/new.html.haml_spec.rb index 3faa2e924..21e89e997 100644 --- a/spec/views/harvests/new.html.haml_spec.rb +++ b/spec/views/harvests/new.html.haml_spec.rb @@ -2,25 +2,16 @@ require 'spec_helper' describe "harvests/new" do before(:each) do - assign(:harvest, stub_model(Harvest, - :crop_id => 1, - :owner_id => 1, - :quantity => "9.99", - :units => "MyString", - :notes => "MyText" - ).as_new_record) + assign(:harvest, FactoryGirl.create(:harvest)) + render end it "renders new harvest form" do - render - - # Run the generator again with the --webrat flag if you want to use webrat matchers assert_select "form", :action => harvests_path, :method => "post" do - assert_select "input#harvest_crop_id", :name => "harvest[crop_id]" - assert_select "input#harvest_owner_id", :name => "harvest[owner_id]" + assert_select "select#harvest_crop_id", :name => "harvest[crop_id]" assert_select "input#harvest_quantity", :name => "harvest[quantity]" assert_select "input#harvest_units", :name => "harvest[units]" - assert_select "textarea#harvest_notes", :name => "harvest[notes]" + assert_select "textarea#harvest_description", :name => "harvest[description]" end end end diff --git a/spec/views/harvests/show.html.haml_spec.rb b/spec/views/harvests/show.html.haml_spec.rb index f726d0a8e..403076851 100644 --- a/spec/views/harvests/show.html.haml_spec.rb +++ b/spec/views/harvests/show.html.haml_spec.rb @@ -2,22 +2,16 @@ require 'spec_helper' describe "harvests/show" do before(:each) do - @harvest = assign(:harvest, stub_model(Harvest, - :crop_id => 1, - :owner_id => 2, - :quantity => "9.99", - :units => "Units", - :notes => "MyText" - )) + controller.stub(:current_user) { nil } + @crop = FactoryGirl.create(:tomato) + @harvest = assign(:harvest, FactoryGirl.create(:harvest, :crop => @crop)) + render end - it "renders attributes in

" do - render - # Run the generator again with the --webrat flag if you want to use webrat matchers - rendered.should match(/1/) - rendered.should match(/2/) - rendered.should match(/9.99/) - rendered.should match(/Units/) - rendered.should match(/MyText/) + it "renders attributes" do + rendered.should contain @crop.system_name + rendered.should contain @harvest.harvested_at.to_s + rendered.should contain "9.99 kg" end + end From 40ce4ab77b00e4fd09db1afe43574181af20690c Mon Sep 17 00:00:00 2001 From: Skud Date: Tue, 17 Sep 2013 17:26:18 +1000 Subject: [PATCH 08/28] Validate units (must be one of individual/bunches/kg/lb) Also changed "units" attribute to "unit". Oops, we weren't following the Rails naming convention. --- app/models/harvest.rb | 7 ++++++- app/views/harvests/_form.html.haml | 2 +- app/views/harvests/index.html.haml | 2 +- app/views/harvests/show.html.haml | 2 +- db/migrate/20130917071545_change_harvest_units_to_unit.rb | 5 +++++ db/schema.rb | 4 ++-- spec/factories/harvests.rb | 2 +- spec/views/harvests/edit.html.haml_spec.rb | 2 +- spec/views/harvests/new.html.haml_spec.rb | 2 +- 9 files changed, 19 insertions(+), 9 deletions(-) create mode 100644 db/migrate/20130917071545_change_harvest_units_to_unit.rb diff --git a/app/models/harvest.rb b/app/models/harvest.rb index 48e6ede26..8e54b31f6 100644 --- a/app/models/harvest.rb +++ b/app/models/harvest.rb @@ -1,7 +1,12 @@ class Harvest < ActiveRecord::Base - attr_accessible :crop_id, :harvested_at, :description, :owner_id, :quantity, :units + attr_accessible :crop_id, :harvested_at, :description, :owner_id, :quantity, :unit belongs_to :crop belongs_to :owner, :class_name => 'Member' + UNITS_VALUES = %w(individual bunches kg lb) + validates :unit, :inclusion => { :in => UNITS_VALUES, + :message => "%{value} is not a valid unit" }, + :allow_nil => true, + :allow_blank => true end diff --git a/app/views/harvests/_form.html.haml b/app/views/harvests/_form.html.haml index 31f90bd30..99926a892 100644 --- a/app/views/harvests/_form.html.haml +++ b/app/views/harvests/_form.html.haml @@ -22,7 +22,7 @@ = f.label 'How many?', :class => 'control-label' .controls = f.number_field :quantity, :class => 'input-small' - = f.text_field :units, :class => 'input-small' + = f.select(:unit, Harvest::UNITS_VALUES, {:include_blank => false}, :class => 'input-medium') .control-group = f.label 'Notes', :class => 'control-label' diff --git a/app/views/harvests/index.html.haml b/app/views/harvests/index.html.haml index e0b96b981..647e66b3b 100644 --- a/app/views/harvests/index.html.haml +++ b/app/views/harvests/index.html.haml @@ -41,7 +41,7 @@ %td - if harvest.quantity = harvest.quantity - = harvest.units + = harvest.unit %td= harvest.description %td= link_to 'Details', harvest, :class => 'btn btn-mini' diff --git a/app/views/harvests/show.html.haml b/app/views/harvests/show.html.haml index 7f866858b..cd2f2666e 100644 --- a/app/views/harvests/show.html.haml +++ b/app/views/harvests/show.html.haml @@ -9,7 +9,7 @@ %b Quantity: - if ! @harvest.quantity.blank? = @harvest.quantity - = @harvest.units + = @harvest.unit - else not specified diff --git a/db/migrate/20130917071545_change_harvest_units_to_unit.rb b/db/migrate/20130917071545_change_harvest_units_to_unit.rb new file mode 100644 index 000000000..d843c2c3d --- /dev/null +++ b/db/migrate/20130917071545_change_harvest_units_to_unit.rb @@ -0,0 +1,5 @@ +class ChangeHarvestUnitsToUnit < ActiveRecord::Migration + def change + rename_column :harvests, :units, :unit + end +end diff --git a/db/schema.rb b/db/schema.rb index 19237834b..3a8149843 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20130917060257) do +ActiveRecord::Schema.define(:version => 20130917071545) do create_table "account_types", :force => true do |t| t.string "name", :null => false @@ -92,7 +92,7 @@ ActiveRecord::Schema.define(:version => 20130917060257) do t.integer "owner_id", :null => false t.date "harvested_at" t.decimal "quantity" - t.string "units" + t.string "unit" t.text "description" t.datetime "created_at", :null => false t.datetime "updated_at", :null => false diff --git a/spec/factories/harvests.rb b/spec/factories/harvests.rb index 6b9e336e9..40f5c15fb 100644 --- a/spec/factories/harvests.rb +++ b/spec/factories/harvests.rb @@ -6,7 +6,7 @@ FactoryGirl.define do owner harvested_at "2013-09-17" quantity "9.99" - units "kg" + unit "kg" description "A lovely harvest" end end diff --git a/spec/views/harvests/edit.html.haml_spec.rb b/spec/views/harvests/edit.html.haml_spec.rb index dd26b7926..d2f50b5f1 100644 --- a/spec/views/harvests/edit.html.haml_spec.rb +++ b/spec/views/harvests/edit.html.haml_spec.rb @@ -10,7 +10,7 @@ describe "harvests/edit" do assert_select "form", :action => harvests_path, :method => "post" do assert_select "select#harvest_crop_id", :name => "harvest[crop_id]" assert_select "input#harvest_quantity", :name => "harvest[quantity]" - assert_select "input#harvest_units", :name => "harvest[units]" + assert_select "input#harvest_unit", :name => "harvest[unit]" assert_select "textarea#harvest_description", :name => "harvest[description]" end end diff --git a/spec/views/harvests/new.html.haml_spec.rb b/spec/views/harvests/new.html.haml_spec.rb index 21e89e997..353dff98c 100644 --- a/spec/views/harvests/new.html.haml_spec.rb +++ b/spec/views/harvests/new.html.haml_spec.rb @@ -10,7 +10,7 @@ describe "harvests/new" do assert_select "form", :action => harvests_path, :method => "post" do assert_select "select#harvest_crop_id", :name => "harvest[crop_id]" assert_select "input#harvest_quantity", :name => "harvest[quantity]" - assert_select "input#harvest_units", :name => "harvest[units]" + assert_select "input#harvest_unit", :name => "harvest[unit]" assert_select "textarea#harvest_description", :name => "harvest[description]" end end From c63fc977360d941a725894c9855afededd133ffe Mon Sep 17 00:00:00 2001 From: Skud Date: Tue, 17 Sep 2013 17:56:00 +1000 Subject: [PATCH 09/28] Validate quantity/unit for harvests If quantity is blank, we also set unit to blank. --- app/models/harvest.rb | 12 +++++++++ spec/models/harvest_spec.rb | 50 +++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/app/models/harvest.rb b/app/models/harvest.rb index 8e54b31f6..a8784832e 100644 --- a/app/models/harvest.rb +++ b/app/models/harvest.rb @@ -4,9 +4,21 @@ class Harvest < ActiveRecord::Base belongs_to :crop belongs_to :owner, :class_name => 'Member' + validates :quantity, + :numericality => { :only_integer => false }, + :allow_nil => true + UNITS_VALUES = %w(individual bunches kg lb) validates :unit, :inclusion => { :in => UNITS_VALUES, :message => "%{value} is not a valid unit" }, :allow_nil => true, :allow_blank => true + + after_validation :clear_unit_if_qty_is_blank + + def clear_unit_if_qty_is_blank + if quantity.blank? + self.unit = nil + end + end end diff --git a/spec/models/harvest_spec.rb b/spec/models/harvest_spec.rb index 7b3872161..ba49bf4dc 100644 --- a/spec/models/harvest_spec.rb +++ b/spec/models/harvest_spec.rb @@ -12,4 +12,54 @@ describe Harvest do harvest.crop.should be_an_instance_of Crop end + context 'quantity' do + it 'allows numeric quantities' do + @harvest = FactoryGirl.build(:harvest, :quantity => 33) + @harvest.should be_valid + end + + it 'allows decimal quantities' do + @harvest = FactoryGirl.build(:harvest, :quantity => 3.3) + @harvest.should be_valid + end + + it 'allows blank quantities' do + @harvest = FactoryGirl.build(:harvest, :quantity => '') + @harvest.should be_valid + end + + it 'allows nil quantities' do + @harvest = FactoryGirl.build(:harvest, :quantity => nil) + @harvest.should be_valid + end + + it "doesn't allow non-numeric quantities" do + @harvest = FactoryGirl.build(:harvest, :quantity => "99a") + @harvest.should_not be_valid + end + end + + context 'units' do + it 'all valid units should work' do + ['individual', 'bunches', 'kg', 'lb', nil, ''].each do |s| + @harvest = FactoryGirl.build(:harvest, :unit=> s) + @harvest.should be_valid + end + end + + it 'should refuse invalid unit values' do + @harvest = FactoryGirl.build(:harvest, :unit => 'not valid') + @harvest.should_not be_valid + @harvest.errors[:unit].should include("not valid is not a valid unit") + end + + it 'sets unit to blank if quantity is blank' do + @harvest = FactoryGirl.build(:harvest, :quantity => '', :unit => 'kg') + @harvest.should be_valid + @harvest.unit.should eq nil + end + end + + + end From 9667f438747a6f6704ecbbc10ba827732ccfb24e Mon Sep 17 00:00:00 2001 From: Skud Date: Tue, 17 Sep 2013 18:02:48 +1000 Subject: [PATCH 10/28] Added friendly urls to harvests --- app/models/harvest.rb | 11 ++++++++++- db/migrate/20130917075803_add_slug_to_harvests.rb | 5 +++++ db/schema.rb | 3 ++- 3 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 db/migrate/20130917075803_add_slug_to_harvests.rb diff --git a/app/models/harvest.rb b/app/models/harvest.rb index a8784832e..a0e82f1a8 100644 --- a/app/models/harvest.rb +++ b/app/models/harvest.rb @@ -1,5 +1,9 @@ class Harvest < ActiveRecord::Base - attr_accessible :crop_id, :harvested_at, :description, :owner_id, :quantity, :unit + extend FriendlyId + friendly_id :harvest_slug, use: :slugged + + attr_accessible :crop_id, :harvested_at, :description, :owner_id, + :quantity, :unit, :slug belongs_to :crop belongs_to :owner, :class_name => 'Member' @@ -21,4 +25,9 @@ class Harvest < ActiveRecord::Base self.unit = nil end end + + def harvest_slug + "#{owner.login_name}-#{crop}".downcase.gsub(' ', '-') + end + end diff --git a/db/migrate/20130917075803_add_slug_to_harvests.rb b/db/migrate/20130917075803_add_slug_to_harvests.rb new file mode 100644 index 000000000..21b44d0ae --- /dev/null +++ b/db/migrate/20130917075803_add_slug_to_harvests.rb @@ -0,0 +1,5 @@ +class AddSlugToHarvests < ActiveRecord::Migration + def change + add_column :harvests, :slug, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 3a8149843..745ebb7d2 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20130917071545) do +ActiveRecord::Schema.define(:version => 20130917075803) do create_table "account_types", :force => true do |t| t.string "name", :null => false @@ -96,6 +96,7 @@ ActiveRecord::Schema.define(:version => 20130917071545) do t.text "description" t.datetime "created_at", :null => false t.datetime "updated_at", :null => false + t.string "slug" end create_table "members", :force => true do |t| From c3c3c435d5d31760c38b636dc173950de15c05c7 Mon Sep 17 00:00:00 2001 From: Skud Date: Tue, 17 Sep 2013 18:28:24 +1000 Subject: [PATCH 11/28] improve display of quantities --- app/helpers/harvests_helper.rb | 15 +++++++++++++++ app/models/harvest.rb | 9 +++++++-- app/views/harvests/index.html.haml | 5 +++-- app/views/harvests/show.html.haml | 6 +----- spec/models/harvest_spec.rb | 2 +- spec/views/harvests/edit.html.haml_spec.rb | 2 +- spec/views/harvests/new.html.haml_spec.rb | 2 +- 7 files changed, 29 insertions(+), 12 deletions(-) diff --git a/app/helpers/harvests_helper.rb b/app/helpers/harvests_helper.rb index 4ef6343a1..d05184fe1 100644 --- a/app/helpers/harvests_helper.rb +++ b/app/helpers/harvests_helper.rb @@ -1,2 +1,17 @@ module HarvestsHelper + +def display_quantity(harvest) + if ! harvest.quantity.blank? + if harvest.unit == 'individual' + number_to_human(harvest.quantity, :strip_insignificant_zeros => true) + elsif harvest.unit == 'bunch' + return pluralize(number_to_human(harvest.quantity, :strip_insignificant_zeros => true), harvest.unit) + else + return "#{number_to_human(harvest.quantity, :strip_insignificant_zeros => true)} #{harvest.unit}" + end + else + return 'not specified' + end +end + end diff --git a/app/models/harvest.rb b/app/models/harvest.rb index a0e82f1a8..12ee61663 100644 --- a/app/models/harvest.rb +++ b/app/models/harvest.rb @@ -12,8 +12,13 @@ class Harvest < ActiveRecord::Base :numericality => { :only_integer => false }, :allow_nil => true - UNITS_VALUES = %w(individual bunches kg lb) - validates :unit, :inclusion => { :in => UNITS_VALUES, + UNITS_VALUES = { + "individual" => "individual", + "bunches" => "bunch", + "kg" => "kg", + "lb" => "lb" + } + validates :unit, :inclusion => { :in => UNITS_VALUES.values, :message => "%{value} is not a valid unit" }, :allow_nil => true, :allow_blank => true diff --git a/app/views/harvests/index.html.haml b/app/views/harvests/index.html.haml index 647e66b3b..33cd6687b 100644 --- a/app/views/harvests/index.html.haml +++ b/app/views/harvests/index.html.haml @@ -29,6 +29,7 @@ - unless @owner %th Owner %th Crop + %th Date %th Quantity %th Description %th @@ -38,10 +39,10 @@ - unless @owner %td= link_to harvest.owner.login_name, harvest.owner %td= link_to harvest.crop.system_name, harvest.crop + %td= harvest.harvested_at %td - if harvest.quantity - = harvest.quantity - = harvest.unit + = display_quantity(harvest) %td= harvest.description %td= link_to 'Details', harvest, :class => 'btn btn-mini' diff --git a/app/views/harvests/show.html.haml b/app/views/harvests/show.html.haml index cd2f2666e..b3ccbd866 100644 --- a/app/views/harvests/show.html.haml +++ b/app/views/harvests/show.html.haml @@ -7,11 +7,7 @@ = @harvest.harvested_at ? @harvest.harvested_at : "not specified" %p %b Quantity: - - if ! @harvest.quantity.blank? - = @harvest.quantity - = @harvest.unit - - else - not specified + = display_quantity(@harvest) - if can? :edit, @harvest or can? :destroy, @harvest %p diff --git a/spec/models/harvest_spec.rb b/spec/models/harvest_spec.rb index ba49bf4dc..8c2896b7a 100644 --- a/spec/models/harvest_spec.rb +++ b/spec/models/harvest_spec.rb @@ -41,7 +41,7 @@ describe Harvest do context 'units' do it 'all valid units should work' do - ['individual', 'bunches', 'kg', 'lb', nil, ''].each do |s| + ['individual', 'bunch', 'kg', 'lb', nil, ''].each do |s| @harvest = FactoryGirl.build(:harvest, :unit=> s) @harvest.should be_valid end diff --git a/spec/views/harvests/edit.html.haml_spec.rb b/spec/views/harvests/edit.html.haml_spec.rb index d2f50b5f1..798f81fea 100644 --- a/spec/views/harvests/edit.html.haml_spec.rb +++ b/spec/views/harvests/edit.html.haml_spec.rb @@ -10,7 +10,7 @@ describe "harvests/edit" do assert_select "form", :action => harvests_path, :method => "post" do assert_select "select#harvest_crop_id", :name => "harvest[crop_id]" assert_select "input#harvest_quantity", :name => "harvest[quantity]" - assert_select "input#harvest_unit", :name => "harvest[unit]" + assert_select "select#harvest_unit", :name => "harvest[unit]" assert_select "textarea#harvest_description", :name => "harvest[description]" end end diff --git a/spec/views/harvests/new.html.haml_spec.rb b/spec/views/harvests/new.html.haml_spec.rb index 353dff98c..f132e127c 100644 --- a/spec/views/harvests/new.html.haml_spec.rb +++ b/spec/views/harvests/new.html.haml_spec.rb @@ -10,7 +10,7 @@ describe "harvests/new" do assert_select "form", :action => harvests_path, :method => "post" do assert_select "select#harvest_crop_id", :name => "harvest[crop_id]" assert_select "input#harvest_quantity", :name => "harvest[quantity]" - assert_select "input#harvest_unit", :name => "harvest[unit]" + assert_select "select#harvest_unit", :name => "harvest[unit]" assert_select "textarea#harvest_description", :name => "harvest[description]" end end From 4ba7a3a48ed5f7a0beb4a454fa9fac84cf926a1c Mon Sep 17 00:00:00 2001 From: Skud Date: Mon, 23 Sep 2013 10:03:22 +1000 Subject: [PATCH 12/28] added harvest link to signed-in homepage --- app/views/home/index.html.haml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/views/home/index.html.haml b/app/views/home/index.html.haml index b39e55ba5..7753ddba9 100644 --- a/app/views/home/index.html.haml +++ b/app/views/home/index.html.haml @@ -11,6 +11,7 @@ %li{ :style => 'padding-left: 0px' } %strong Quick links: %li= link_to "Plant something", new_planting_path + %li= link_to "Harvest something", new_harvest_path %li= link_to "Add seeds", new_seed_path %li= link_to "Post", new_post_path %li= link_to "Edit profile", edit_member_registration_path From c5e8e4298f7c1abf65df71252cee85797c8d2d02 Mon Sep 17 00:00:00 2001 From: Skud Date: Wed, 25 Sep 2013 15:34:17 +1000 Subject: [PATCH 13/28] Separated informal/human units from measured weights --- app/helpers/harvests_helper.rb | 43 +++++++--- app/models/harvest.rb | 26 +++++- app/views/harvests/_form.html.haml | 6 ++ .../20130925050304_add_weight_to_harvests.rb | 6 ++ db/schema.rb | 12 +-- spec/factories/harvests.rb | 6 +- spec/helpers/harvests_helper_spec.rb | 79 +++++++++++++++++++ spec/models/harvest_spec.rb | 49 +++++++++++- spec/views/harvests/edit.html.haml_spec.rb | 2 + spec/views/harvests/new.html.haml_spec.rb | 2 + spec/views/harvests/show.html.haml_spec.rb | 1 - 11 files changed, 208 insertions(+), 24 deletions(-) create mode 100644 db/migrate/20130925050304_add_weight_to_harvests.rb create mode 100644 spec/helpers/harvests_helper_spec.rb diff --git a/app/helpers/harvests_helper.rb b/app/helpers/harvests_helper.rb index d05184fe1..a6078dc60 100644 --- a/app/helpers/harvests_helper.rb +++ b/app/helpers/harvests_helper.rb @@ -1,17 +1,40 @@ module HarvestsHelper -def display_quantity(harvest) - if ! harvest.quantity.blank? - if harvest.unit == 'individual' - number_to_human(harvest.quantity, :strip_insignificant_zeros => true) - elsif harvest.unit == 'bunch' - return pluralize(number_to_human(harvest.quantity, :strip_insignificant_zeros => true), harvest.unit) + def display_quantity(harvest) + human_quantity = display_human_quantity(harvest) + weight = display_weight(harvest) + + if human_quantity && weight + return "#{human_quantity}, weighing #{weight}" + elsif human_quantity + return human_quantity + elsif weight + return weight else - return "#{number_to_human(harvest.quantity, :strip_insignificant_zeros => true)} #{harvest.unit}" + return 'not specified' + end + end + + def display_human_quantity(harvest) + if ! harvest.quantity.blank? && harvest.quantity > 0 + if harvest.unit == 'individual' + number_to_human(harvest.quantity, :strip_insignificant_zeros => true) + elsif harvest.unit == 'bunch' + return pluralize(number_to_human(harvest.quantity, :strip_insignificant_zeros => true), harvest.unit) + else + return "#{number_to_human(harvest.quantity, :strip_insignificant_zeros => true)} #{harvest.unit}" + end + else + return nil + end + end + + def display_weight(harvest) + if ! harvest.weight_quantity.blank? && harvest.weight_quantity > 0 + return "#{number_to_human(harvest.weight_quantity, :strip_insignificant_zeros => true)} #{harvest.weight_unit}" + else + return nil end - else - return 'not specified' end -end end diff --git a/app/models/harvest.rb b/app/models/harvest.rb index 12ee61663..165655b55 100644 --- a/app/models/harvest.rb +++ b/app/models/harvest.rb @@ -3,7 +3,7 @@ class Harvest < ActiveRecord::Base friendly_id :harvest_slug, use: :slugged attr_accessible :crop_id, :harvested_at, :description, :owner_id, - :quantity, :unit, :slug + :quantity, :unit, :weight_quantity, :weight_unit, :slug belongs_to :crop belongs_to :owner, :class_name => 'Member' @@ -14,16 +14,28 @@ class Harvest < ActiveRecord::Base UNITS_VALUES = { "individual" => "individual", - "bunches" => "bunch", - "kg" => "kg", - "lb" => "lb" + "bunches" => "bunch" } validates :unit, :inclusion => { :in => UNITS_VALUES.values, :message => "%{value} is not a valid unit" }, :allow_nil => true, :allow_blank => true + validates :weight_quantity, + :numericality => { :only_integer => false }, + :allow_nil => true + + WEIGHT_UNITS_VALUES = { + "kg" => "kg", + "lb" => "lb" + } + validates :weight_unit, :inclusion => { :in => WEIGHT_UNITS_VALUES.values, + :message => "%{value} is not a valid unit" }, + :allow_nil => true, + :allow_blank => true + after_validation :clear_unit_if_qty_is_blank + after_validation :clear_weight_unit_if_weight_qty_is_blank def clear_unit_if_qty_is_blank if quantity.blank? @@ -31,6 +43,12 @@ class Harvest < ActiveRecord::Base end end + def clear_weight_unit_if_weight_qty_is_blank + if weight_quantity.blank? + self.weight_unit = nil + end + end + def harvest_slug "#{owner.login_name}-#{crop}".downcase.gsub(' ', '-') end diff --git a/app/views/harvests/_form.html.haml b/app/views/harvests/_form.html.haml index 99926a892..d56904ff7 100644 --- a/app/views/harvests/_form.html.haml +++ b/app/views/harvests/_form.html.haml @@ -24,6 +24,12 @@ = f.number_field :quantity, :class => 'input-small' = f.select(:unit, Harvest::UNITS_VALUES, {:include_blank => false}, :class => 'input-medium') + .control-group + = f.label 'Weighing:', :class => 'control-label' + .controls + = f.number_field :weight_quantity, :class => 'input-small' + = f.select(:weight_unit, Harvest::WEIGHT_UNITS_VALUES, {:include_blank => false}, :class => 'input-medium') + in total .control-group = f.label 'Notes', :class => 'control-label' .controls= f.text_area :description, :rows => 6 diff --git a/db/migrate/20130925050304_add_weight_to_harvests.rb b/db/migrate/20130925050304_add_weight_to_harvests.rb new file mode 100644 index 000000000..caf1fd87a --- /dev/null +++ b/db/migrate/20130925050304_add_weight_to_harvests.rb @@ -0,0 +1,6 @@ +class AddWeightToHarvests < ActiveRecord::Migration + def change + add_column :harvests, :weight_quantity, :decimal + add_column :harvests, :weight_unit, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 745ebb7d2..1aafa8c89 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20130917075803) do +ActiveRecord::Schema.define(:version => 20130925050304) do create_table "account_types", :force => true do |t| t.string "name", :null => false @@ -88,15 +88,17 @@ ActiveRecord::Schema.define(:version => 20130917075803) do add_index "gardens", ["slug"], :name => "index_gardens_on_slug", :unique => true create_table "harvests", :force => true do |t| - t.integer "crop_id", :null => false - t.integer "owner_id", :null => false + t.integer "crop_id", :null => false + t.integer "owner_id", :null => false t.date "harvested_at" t.decimal "quantity" t.string "unit" t.text "description" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false t.string "slug" + t.decimal "weight_quantity" + t.string "weight_unit" end create_table "members", :force => true do |t| diff --git a/spec/factories/harvests.rb b/spec/factories/harvests.rb index 40f5c15fb..407ccc875 100644 --- a/spec/factories/harvests.rb +++ b/spec/factories/harvests.rb @@ -5,8 +5,10 @@ FactoryGirl.define do crop owner harvested_at "2013-09-17" - quantity "9.99" - unit "kg" + quantity "3" + unit "individual" + weight_quantity 6 + weight_unit "kg" description "A lovely harvest" end end diff --git a/spec/helpers/harvests_helper_spec.rb b/spec/helpers/harvests_helper_spec.rb new file mode 100644 index 000000000..ecc30a51e --- /dev/null +++ b/spec/helpers/harvests_helper_spec.rb @@ -0,0 +1,79 @@ +require 'spec_helper' + +describe HarvestsHelper do + describe "display_quantity" do + + it "blank" do + harvest = FactoryGirl.create(:harvest, + :quantity => nil, + :weight_quantity => nil + ) + result = helper.display_quantity(harvest) + result.should eq 'not specified' + end + + it '3 individual' do + harvest = FactoryGirl.create(:harvest, + :quantity => 3, + :unit => 'individual', + :weight_quantity => nil + ) + result = helper.display_quantity(harvest) + result.should eq '3' + end + + it '1 bunch' do + harvest = FactoryGirl.create(:harvest, + :quantity => 1, + :unit => 'bunch', + :weight_quantity => nil + ) + result = helper.display_quantity(harvest) + result.should eq '1 bunch' + end + + it '3 bunches' do + harvest = FactoryGirl.create(:harvest, + :quantity => 3, + :unit => 'bunch', + :weight_quantity => nil + ) + result = helper.display_quantity(harvest) + result.should eq '3 bunches' + end + + it '3 kg' do + harvest = FactoryGirl.create(:harvest, + :quantity => nil, + :unit => nil, + :weight_quantity => 3, + :weight_unit => 'kg' + ) + result = helper.display_quantity(harvest) + result.should eq '3 kg' + end + + it '3 individual weighing 3 kg' do + harvest = FactoryGirl.create(:harvest, + :quantity => 3, + :unit => 'individual', + :weight_quantity => 3, + :weight_unit => 'kg' + ) + result = helper.display_quantity(harvest) + result.should eq '3, weighing 3 kg' + end + + it '3 bunches weighing 3 kg' do + harvest = FactoryGirl.create(:harvest, + :quantity => 3, + :unit => 'bunch', + :weight_quantity => 3, + :weight_unit => 'kg' + ) + result = helper.display_quantity(harvest) + result.should eq '3 bunches, weighing 3 kg' + end + + end +end diff --git a/spec/models/harvest_spec.rb b/spec/models/harvest_spec.rb index 8c2896b7a..e771f2a13 100644 --- a/spec/models/harvest_spec.rb +++ b/spec/models/harvest_spec.rb @@ -41,7 +41,7 @@ describe Harvest do context 'units' do it 'all valid units should work' do - ['individual', 'bunch', 'kg', 'lb', nil, ''].each do |s| + ['individual', 'bunch', nil, ''].each do |s| @harvest = FactoryGirl.build(:harvest, :unit=> s) @harvest.should be_valid end @@ -54,12 +54,57 @@ describe Harvest do end it 'sets unit to blank if quantity is blank' do - @harvest = FactoryGirl.build(:harvest, :quantity => '', :unit => 'kg') + @harvest = FactoryGirl.build(:harvest, :quantity => '', :unit => 'individual') @harvest.should be_valid @harvest.unit.should eq nil end end + context 'weight quantity' do + it 'allows numeric weight quantities' do + @harvest = FactoryGirl.build(:harvest, :weight_quantity => 33) + @harvest.should be_valid + end + it 'allows decimal weight quantities' do + @harvest = FactoryGirl.build(:harvest, :weight_quantity => 3.3) + @harvest.should be_valid + end + it 'allows blank weight quantities' do + @harvest = FactoryGirl.build(:harvest, :weight_quantity => '') + @harvest.should be_valid + end + + it 'allows nil weight quantities' do + @harvest = FactoryGirl.build(:harvest, :weight_quantity => nil) + @harvest.should be_valid + end + + it "doesn't allow non-numeric weight quantities" do + @harvest = FactoryGirl.build(:harvest, :weight_quantity => "99a") + @harvest.should_not be_valid + end + end + + context 'weight units' do + it 'all valid units should work' do + ['kg', 'lb', nil, ''].each do |s| + @harvest = FactoryGirl.build(:harvest, :weight_unit => s) + @harvest.should be_valid + end + end + + it 'should refuse invalid weight unit values' do + @harvest = FactoryGirl.build(:harvest, :weight_unit => 'not valid') + @harvest.should_not be_valid + @harvest.errors[:weight_unit].should include("not valid is not a valid unit") + end + + it 'sets weight_unit to blank if quantity is blank' do + @harvest = FactoryGirl.build(:harvest, :weight_quantity => '', :weight_unit => 'kg') + @harvest.should be_valid + @harvest.weight_unit.should eq nil + end + end end diff --git a/spec/views/harvests/edit.html.haml_spec.rb b/spec/views/harvests/edit.html.haml_spec.rb index 798f81fea..ad3f257e0 100644 --- a/spec/views/harvests/edit.html.haml_spec.rb +++ b/spec/views/harvests/edit.html.haml_spec.rb @@ -10,7 +10,9 @@ describe "harvests/edit" do assert_select "form", :action => harvests_path, :method => "post" do assert_select "select#harvest_crop_id", :name => "harvest[crop_id]" assert_select "input#harvest_quantity", :name => "harvest[quantity]" + assert_select "input#harvest_weight_quantity", :name => "harvest[quantity]" assert_select "select#harvest_unit", :name => "harvest[unit]" + assert_select "select#harvest_weight_unit", :name => "harvest[unit]" assert_select "textarea#harvest_description", :name => "harvest[description]" end end diff --git a/spec/views/harvests/new.html.haml_spec.rb b/spec/views/harvests/new.html.haml_spec.rb index f132e127c..14a1c69d6 100644 --- a/spec/views/harvests/new.html.haml_spec.rb +++ b/spec/views/harvests/new.html.haml_spec.rb @@ -10,7 +10,9 @@ describe "harvests/new" do assert_select "form", :action => harvests_path, :method => "post" do assert_select "select#harvest_crop_id", :name => "harvest[crop_id]" assert_select "input#harvest_quantity", :name => "harvest[quantity]" + assert_select "input#harvest_weight_quantity", :name => "harvest[quantity]" assert_select "select#harvest_unit", :name => "harvest[unit]" + assert_select "select#harvest_weight_unit", :name => "harvest[unit]" assert_select "textarea#harvest_description", :name => "harvest[description]" end end diff --git a/spec/views/harvests/show.html.haml_spec.rb b/spec/views/harvests/show.html.haml_spec.rb index 403076851..ef233aedc 100644 --- a/spec/views/harvests/show.html.haml_spec.rb +++ b/spec/views/harvests/show.html.haml_spec.rb @@ -11,7 +11,6 @@ describe "harvests/show" do it "renders attributes" do rendered.should contain @crop.system_name rendered.should contain @harvest.harvested_at.to_s - rendered.should contain "9.99 kg" end end From 1202a481317506807c7f267c1787b3a336bf275f Mon Sep 17 00:00:00 2001 From: Skud Date: Wed, 25 Sep 2013 15:51:04 +1000 Subject: [PATCH 14/28] Tweaked crop CSV to include added_by and license --- app/views/crops/index.csv.shaper | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/app/views/crops/index.csv.shaper b/app/views/crops/index.csv.shaper index 456e2cb7e..d186c0099 100644 --- a/app/views/crops/index.csv.shaper +++ b/app/views/crops/index.csv.shaper @@ -20,11 +20,16 @@ csv.headers :id, :system_name, :planted_from_advanced_plant, :planted_from_graft, :planted_from_layering, + :added_by_member_id, + :added_by_member_name, :date_added, - :last_modified + :last_modified, + :license @crops.each do |c| csv.row c do |csv, crop| + + csv.cells :id, :system_name, :en_wikipedia_url csv.cell :growstuff_url, crop_url(c) @@ -67,8 +72,12 @@ csv.headers :id, :system_name, csv.cell :planted_from_graft, planted_from['graft'] csv.cell :planted_from_layering, planted_from['layering'] + csv.cell :added_by_member_id, c.creator.id + csv.cell :added_by_member_name, c.creator.to_s csv.cell :date_added, c.created_at.to_s(:db) csv.cell :last_modified, c.updated_at.to_s(:db) + csv.cell :license, "CC-BY-SA Growstuff http://growstuff.org/" + end end From 92ebf1a43c521877927bca6eac7c88051c7c38b3 Mon Sep 17 00:00:00 2001 From: Skud Date: Wed, 25 Sep 2013 16:02:40 +1000 Subject: [PATCH 15/28] Added harvest CSV --- app/controllers/crops_controller.rb | 2 +- app/controllers/harvests_controller.rb | 5 ++++ app/views/harvests/index.csv.shaper | 41 ++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 app/views/harvests/index.csv.shaper diff --git a/app/controllers/crops_controller.rb b/app/controllers/crops_controller.rb index 0892acb33..d93d51e7b 100644 --- a/app/controllers/crops_controller.rb +++ b/app/controllers/crops_controller.rb @@ -15,7 +15,7 @@ class CropsController < ApplicationController format.rss { render :layout => false } format.csv do @filename = "Growstuff-Crops-#{Time.zone.now.to_s(:number)}.csv" - @crops = Crop.includes(:scientific_names, :plantings, :seeds) + @crops = Crop.includes(:scientific_names, :plantings, :seeds, :creator) render :csv => @crops end end diff --git a/app/controllers/harvests_controller.rb b/app/controllers/harvests_controller.rb index 1c529df87..9c8810566 100644 --- a/app/controllers/harvests_controller.rb +++ b/app/controllers/harvests_controller.rb @@ -15,6 +15,11 @@ class HarvestsController < ApplicationController respond_to do |format| format.html # index.html.erb format.json { render json: @harvests } + format.csv do + @filename = "Growstuff-Harvests-#{Time.zone.now.to_s(:number)}.csv" + @harvests = Harvest.includes(:owner, :crop) + render :csv => @harvests + end end end diff --git a/app/views/harvests/index.csv.shaper b/app/views/harvests/index.csv.shaper new file mode 100644 index 000000000..1fd9c1fd5 --- /dev/null +++ b/app/views/harvests/index.csv.shaper @@ -0,0 +1,41 @@ +csv.headers :id, + :growstuff_url, + :owner_id, + :owner_name, + :crop_id, + :crop_name, + :quantity, + :unit, + :weight_quantity, + :weight_unit, + :date_harvested, + :description, + :date_added, + :last_modified, + :license + +@harvests.each do |h| + csv.row h do |csv, harvest| + + csv.cell :id + csv.cell :growstuff_url, harvest_url(h) + + csv.cell :owner_id, h.owner.id + csv.cell :owner_name, h.owner.to_s + + csv.cell :crop_id, h.crop.id + csv.cell :crop_name, h.crop.to_s + + csv.cells :quantity, :unit, :weight_quantity, :weight_unit + + csv.cell :date_harvested, h.created_at.to_s(:db) + + csv.cell :description + + csv.cell :date_added, h.created_at.to_s(:db) + csv.cell :last_modified, h.updated_at.to_s(:db) + + csv.cell :license, "CC-BY-SA Growstuff http://growstuff.org/" + + end +end From c452d3871783f3cf4bb893cf029110d51354044d Mon Sep 17 00:00:00 2001 From: Skud Date: Wed, 25 Sep 2013 16:07:22 +1000 Subject: [PATCH 16/28] If quantity == 0, set it to nil --- app/models/harvest.rb | 15 ++++++++++----- spec/models/harvest_spec.rb | 10 ++++++++++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/app/models/harvest.rb b/app/models/harvest.rb index 165655b55..60dbae1e7 100644 --- a/app/models/harvest.rb +++ b/app/models/harvest.rb @@ -34,16 +34,21 @@ class Harvest < ActiveRecord::Base :allow_nil => true, :allow_blank => true - after_validation :clear_unit_if_qty_is_blank - after_validation :clear_weight_unit_if_weight_qty_is_blank + after_validation :cleanup_quantities + + def cleanup_quantities + if quantity == 0 + self.quantity = nil + end - def clear_unit_if_qty_is_blank if quantity.blank? self.unit = nil end - end - def clear_weight_unit_if_weight_qty_is_blank + if weight_quantity == 0 + self.weight_quantity = nil + end + if weight_quantity.blank? self.weight_unit = nil end diff --git a/spec/models/harvest_spec.rb b/spec/models/harvest_spec.rb index e771f2a13..db590e96c 100644 --- a/spec/models/harvest_spec.rb +++ b/spec/models/harvest_spec.rb @@ -33,6 +33,11 @@ describe Harvest do @harvest.should be_valid end + it 'cleans up zero quantities' do + @harvest = FactoryGirl.build(:harvest, :quantity => 0) + @harvest.quantity.should == 0 + end + it "doesn't allow non-numeric quantities" do @harvest = FactoryGirl.build(:harvest, :quantity => "99a") @harvest.should_not be_valid @@ -81,6 +86,11 @@ describe Harvest do @harvest.should be_valid end + it 'cleans up zero quantities' do + @harvest = FactoryGirl.build(:harvest, :weight_quantity => 0) + @harvest.weight_quantity.should == 0 + end + it "doesn't allow non-numeric weight quantities" do @harvest = FactoryGirl.build(:harvest, :weight_quantity => "99a") @harvest.should_not be_valid From 9cef31e646ff8a940069415466b62f5b929605a2 Mon Sep 17 00:00:00 2001 From: Skud Date: Wed, 25 Sep 2013 16:11:08 +1000 Subject: [PATCH 17/28] allow per-owner CSV downloads --- app/controllers/harvests_controller.rb | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/app/controllers/harvests_controller.rb b/app/controllers/harvests_controller.rb index 9c8810566..96e029ac3 100644 --- a/app/controllers/harvests_controller.rb +++ b/app/controllers/harvests_controller.rb @@ -16,8 +16,13 @@ class HarvestsController < ApplicationController format.html # index.html.erb format.json { render json: @harvests } format.csv do - @filename = "Growstuff-Harvests-#{Time.zone.now.to_s(:number)}.csv" - @harvests = Harvest.includes(:owner, :crop) + if @owner + @filename = "Growstuff-#{@owner}-Harvests-#{Time.zone.now.to_s(:number)}.csv" + @harvests = @owner.harvests.includes(:owner, :crop) + else + @filename = "Growstuff-Harvests-#{Time.zone.now.to_s(:number)}.csv" + @harvests = Harvest.includes(:owner, :crop) + end render :csv => @harvests end end From 0116547c96131e2e3641b0bc9812ad2a43dfc1d9 Mon Sep 17 00:00:00 2001 From: Skud Date: Wed, 25 Sep 2013 16:23:58 +1000 Subject: [PATCH 18/28] added links to CSV and JSON data --- app/views/crops/index.html.haml | 5 +++++ app/views/harvests/index.html.haml | 9 +++++++++ spec/views/crops/index.html.haml_spec.rb | 9 +++++++++ spec/views/harvests/index.html.haml_spec.rb | 7 +++++++ 4 files changed, 30 insertions(+) diff --git a/app/views/crops/index.html.haml b/app/views/crops/index.html.haml index 463d662c5..73dc354d0 100644 --- a/app/views/crops/index.html.haml +++ b/app/views/crops/index.html.haml @@ -22,3 +22,8 @@ = page_entries_info @crops, :model => "crops" = will_paginate @crops + +%ul.inline + %li The data on this page is available in the following formats: + %li= link_to "CSV", crops_path(:format => 'csv') + %li= link_to "JSON", crops_path(:format => 'json') diff --git a/app/views/harvests/index.html.haml b/app/views/harvests/index.html.haml index 33cd6687b..612883330 100644 --- a/app/views/harvests/index.html.haml +++ b/app/views/harvests/index.html.haml @@ -49,3 +49,12 @@ %div.pagination = page_entries_info @harvests, :model => "harvests" = will_paginate @harvests + + %ul.inline + %li The data on this page is available in the following formats: + - if @owner + %li= link_to "CSV", harvests_by_owner_path(@owner, :format => 'csv') + %li= link_to "JSON", harvests_by_owner_path(@owner, :format => 'json') + - else + %li= link_to "CSV", harvests_path(:format => 'csv') + %li= link_to "JSON", harvests_path(:format => 'json') diff --git a/spec/views/crops/index.html.haml_spec.rb b/spec/views/crops/index.html.haml_spec.rb index d61d108be..e7520cb2e 100644 --- a/spec/views/crops/index.html.haml_spec.rb +++ b/spec/views/crops/index.html.haml_spec.rb @@ -45,4 +45,13 @@ describe "crops/index" do rendered.should contain "New Crop" end end + + context "downloads" do + it "offers a CSV download" do + render + rendered.should contain "The data on this page is available in the following formats:" + assert_select "a", :href => crops_path(:format => 'csv') + assert_select "a", :href => crops_path(:format => 'json') + end + end end diff --git a/spec/views/harvests/index.html.haml_spec.rb b/spec/views/harvests/index.html.haml_spec.rb index 9a5712b14..827785aff 100644 --- a/spec/views/harvests/index.html.haml_spec.rb +++ b/spec/views/harvests/index.html.haml_spec.rb @@ -31,4 +31,11 @@ describe "harvests/index" do assert_select "tr>td", :text => @tomato.system_name assert_select "tr>td", :text => @maize.system_name end + + it "provides data links" do + render + rendered.should contain "The data on this page is available in the following formats:" + assert_select "a", :href => harvests_path(:format => 'csv') + assert_select "a", :href => harvests_path(:format => 'json') + end end From 013234c8824ceb319921ee6a5c02e3e773d130a6 Mon Sep 17 00:00:00 2001 From: Skud Date: Wed, 25 Sep 2013 16:57:27 +1000 Subject: [PATCH 19/28] Added CSV for plantings --- app/controllers/plantings_controller.rb | 10 +++++ app/views/plantings/index.csv.shaper | 45 ++++++++++++++++++++ app/views/plantings/index.html.haml | 11 +++++ spec/views/plantings/index.html.haml_spec.rb | 8 ++++ 4 files changed, 74 insertions(+) create mode 100644 app/views/plantings/index.csv.shaper diff --git a/app/controllers/plantings_controller.rb b/app/controllers/plantings_controller.rb index a5b781bab..0d419d2f1 100644 --- a/app/controllers/plantings_controller.rb +++ b/app/controllers/plantings_controller.rb @@ -17,6 +17,16 @@ class PlantingsController < ApplicationController format.html # index.html.erb format.json { render json: @plantings } format.rss { render :layout => false } #index.rss.builder + format.csv do + if @owner + @filename = "Growstuff-#{@owner}-Plantings-#{Time.zone.now.to_s(:number)}.csv" + @plantings = @owner.plantings.includes(:owner, :crop, :garden) + else + @filename = "Growstuff-Plantings-#{Time.zone.now.to_s(:number)}.csv" + @plantings = Planting.includes(:owner, :crop, :garden) + end + render :csv => @plantings + end end end diff --git a/app/views/plantings/index.csv.shaper b/app/views/plantings/index.csv.shaper new file mode 100644 index 000000000..800fb77fe --- /dev/null +++ b/app/views/plantings/index.csv.shaper @@ -0,0 +1,45 @@ +csv.headers :id, + :growstuff_url, + :owner_id, + :owner_name, + :garden_id, + :garden_name, + :crop_id, + :crop_name, + :quantity, + :planted_from, + :sunniness, + :date_planted, + :description, + :date_added, + :last_modified, + :license + +@plantings.each do |p| + csv.row p do |csv, planting| + + csv.cell :id + csv.cell :growstuff_url, planting_url(p) + + csv.cell :owner_id, p.owner.id + csv.cell :owner_name, p.owner.to_s + + csv.cell :garden_id, p.garden.id + csv.cell :garden_name, p.garden.to_s + + csv.cell :crop_id, p.crop.id + csv.cell :crop_name, p.crop.to_s + + csv.cells :quantity, :planted_from, :sunniness + + csv.cell :date_planted, p.created_at.to_s(:db) + + csv.cell :description + + csv.cell :date_added, p.created_at.to_s(:db) + csv.cell :last_modified, p.updated_at.to_s(:db) + + csv.cell :license, "CC-BY-SA Growstuff http://growstuff.org/" + + end +end diff --git a/app/views/plantings/index.html.haml b/app/views/plantings/index.html.haml index 434669cb9..5a6d73604 100644 --- a/app/views/plantings/index.html.haml +++ b/app/views/plantings/index.html.haml @@ -51,3 +51,14 @@ %div.pagination = page_entries_info @plantings, :model => "plantings" = will_paginate @plantings + + %ul.inline + %li The data on this page is available in the following formats: + - if @owner + %li= link_to "CSV", plantings_by_owner_path(@owner, :format => 'csv') + %li= link_to "JSON", plantings_by_owner_path(@owner, :format => 'json') + %li= link_to "RSS", plantings_by_owner_path(@owner, :format => 'rss') + - else + %li= link_to "CSV", plantings_path(:format => 'csv') + %li= link_to "JSON", plantings_path(:format => 'json') + %li= link_to "RSS", plantings_path(:format => 'rss') diff --git a/spec/views/plantings/index.html.haml_spec.rb b/spec/views/plantings/index.html.haml_spec.rb index a3df530bd..0653afe62 100644 --- a/spec/views/plantings/index.html.haml_spec.rb +++ b/spec/views/plantings/index.html.haml_spec.rb @@ -44,4 +44,12 @@ describe "plantings/index" do rendered.should contain 'January 13, 2013' end + it "provides data links" do + render + rendered.should contain "The data on this page is available in the following formats:" + assert_select "a", :href => plantings_path(:format => 'csv') + assert_select "a", :href => plantings_path(:format => 'json') + assert_select "a", :href => plantings_path(:format => 'rss') + end + end From 9cf770a20093b8cbb67575b7ace665e0a4e1d27f Mon Sep 17 00:00:00 2001 From: Skud Date: Wed, 25 Sep 2013 16:59:28 +1000 Subject: [PATCH 20/28] Adjusted crops.rss to show most recent --- app/controllers/crops_controller.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/controllers/crops_controller.rb b/app/controllers/crops_controller.rb index d93d51e7b..0706f21d2 100644 --- a/app/controllers/crops_controller.rb +++ b/app/controllers/crops_controller.rb @@ -12,7 +12,10 @@ class CropsController < ApplicationController respond_to do |format| format.html format.json { render :json => @crops } - format.rss { render :layout => false } + format.rss do + @crops = Crop.recent.includes(:scientific_names, :creator) + render :rss => @crops + end format.csv do @filename = "Growstuff-Crops-#{Time.zone.now.to_s(:number)}.csv" @crops = Crop.includes(:scientific_names, :plantings, :seeds, :creator) From 9a48edc18718eaaaf55c2058a5d6b73250bdd401 Mon Sep 17 00:00:00 2001 From: Skud Date: Wed, 25 Sep 2013 17:12:58 +1000 Subject: [PATCH 21/28] Fixed erroneous date --- app/views/plantings/index.csv.shaper | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/plantings/index.csv.shaper b/app/views/plantings/index.csv.shaper index 800fb77fe..d62996eb9 100644 --- a/app/views/plantings/index.csv.shaper +++ b/app/views/plantings/index.csv.shaper @@ -32,7 +32,7 @@ csv.headers :id, csv.cells :quantity, :planted_from, :sunniness - csv.cell :date_planted, p.created_at.to_s(:db) + csv.cell :date_planted, p.planted_at.to_s(:db) csv.cell :description From c23f27e8b03c986b5777606fd072a73a2f9167eb Mon Sep 17 00:00:00 2001 From: Skud Date: Wed, 25 Sep 2013 17:14:46 +1000 Subject: [PATCH 22/28] Added CSV for seeds --- app/controllers/seeds_controller.rb | 10 +++++ app/views/seeds/index.csv.shaper | 47 ++++++++++++++++++++++++ app/views/seeds/index.html.haml | 11 ++++++ spec/views/seeds/index.html.haml_spec.rb | 8 ++++ 4 files changed, 76 insertions(+) create mode 100644 app/views/seeds/index.csv.shaper diff --git a/app/controllers/seeds_controller.rb b/app/controllers/seeds_controller.rb index 0af8794d5..30918b12e 100644 --- a/app/controllers/seeds_controller.rb +++ b/app/controllers/seeds_controller.rb @@ -17,6 +17,16 @@ class SeedsController < ApplicationController format.html # index.html.erb format.json { render json: @seeds } format.rss { render :layout => false } #index.rss.builder + format.csv do + if @owner + @filename = "Growstuff-#{@owner}-Seeds-#{Time.zone.now.to_s(:number)}.csv" + @seeds = @owner.seeds.includes(:owner, :crop) + else + @filename = "Growstuff-Seeds-#{Time.zone.now.to_s(:number)}.csv" + @seeds = Seed.includes(:owner, :crop) + end + render :csv => @seeds + end end end diff --git a/app/views/seeds/index.csv.shaper b/app/views/seeds/index.csv.shaper new file mode 100644 index 000000000..ce1f1497b --- /dev/null +++ b/app/views/seeds/index.csv.shaper @@ -0,0 +1,47 @@ +csv.headers :id, + :growstuff_url, + :owner_id, + :owner_name, + :crop_id, + :crop_name, + :quantity, + :plant_before, + :tradable_to, + :from_location, + :latitude, + :longitude, + :description, + :date_added, + :last_modified, + :license + +@seeds.each do |s| + csv.row s do |csv, seed| + + csv.cell :id + csv.cell :growstuff_url, seed_url(s) + + csv.cell :owner_id, s.owner.id + csv.cell :owner_name, s.owner.to_s + + csv.cell :crop_id, s.crop.id + csv.cell :crop_name, s.crop.to_s + + csv.cell :quantity + + csv.cell :plant_before, s.plant_before.to_s(:db) + + csv.cell :tradable_to + csv.cell :from_location, s.owner.location + csv.cell :latitude, s.owner.latitude + csv.cell :longitude, s.owner.longitude + + csv.cell :description + + csv.cell :date_added, s.created_at.to_s(:db) + csv.cell :last_modified, s.updated_at.to_s(:db) + + csv.cell :license, "CC-BY-SA Growstuff http://growstuff.org/" + + end +end diff --git a/app/views/seeds/index.html.haml b/app/views/seeds/index.html.haml index 6f62b07a7..201a4669d 100644 --- a/app/views/seeds/index.html.haml +++ b/app/views/seeds/index.html.haml @@ -56,3 +56,14 @@ %div.pagination = page_entries_info @seeds, :model => "seeds" = will_paginate @seeds + + %ul.inline + %li The data on this page is available in the following formats: + - if @owner + %li= link_to "CSV", seeds_by_owner_path(@owner, :format => 'csv') + %li= link_to "JSON", seeds_by_owner_path(@owner, :format => 'json') + %li= link_to "RSS", seeds_by_owner_path(@owner, :format => 'rss') + - else + %li= link_to "CSV", seeds_path(:format => 'csv') + %li= link_to "JSON", seeds_path(:format => 'json') + %li= link_to "RSS", seeds_path(:format => 'rss') diff --git a/spec/views/seeds/index.html.haml_spec.rb b/spec/views/seeds/index.html.haml_spec.rb index 02d9d2b44..72cb43b24 100644 --- a/spec/views/seeds/index.html.haml_spec.rb +++ b/spec/views/seeds/index.html.haml_spec.rb @@ -42,4 +42,12 @@ describe "seeds/index" do assert_select 'a', :href => place_path(@owner.location) end end + + it "provides data links" do + render + rendered.should contain "The data on this page is available in the following formats:" + assert_select "a", :href => seeds_path(:format => 'csv') + assert_select "a", :href => seeds_path(:format => 'json') + assert_select "a", :href => seeds_path(:format => 'rss') + end end From 233d740df880e3ea590aa1fc9439cfe30593176f Mon Sep 17 00:00:00 2001 From: Skud Date: Tue, 1 Oct 2013 12:21:31 +1000 Subject: [PATCH 23/28] Fixed error with blank planting/plant_before dates --- app/views/plantings/index.csv.shaper | 2 +- app/views/seeds/index.csv.shaper | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/plantings/index.csv.shaper b/app/views/plantings/index.csv.shaper index d62996eb9..becb6d4d8 100644 --- a/app/views/plantings/index.csv.shaper +++ b/app/views/plantings/index.csv.shaper @@ -32,7 +32,7 @@ csv.headers :id, csv.cells :quantity, :planted_from, :sunniness - csv.cell :date_planted, p.planted_at.to_s(:db) + csv.cell :date_planted, p.planted_at ? p.planted_at.to_s(:db) : '' csv.cell :description diff --git a/app/views/seeds/index.csv.shaper b/app/views/seeds/index.csv.shaper index ce1f1497b..818e68909 100644 --- a/app/views/seeds/index.csv.shaper +++ b/app/views/seeds/index.csv.shaper @@ -29,7 +29,7 @@ csv.headers :id, csv.cell :quantity - csv.cell :plant_before, s.plant_before.to_s(:db) + csv.cell :plant_before, s.plant_before ? s.plant_before.to_s(:db) : '' csv.cell :tradable_to csv.cell :from_location, s.owner.location From 668cb33f15f738e4cccab443e62760ab0c5eedb3 Mon Sep 17 00:00:00 2001 From: Skud Date: Tue, 1 Oct 2013 12:35:41 +1000 Subject: [PATCH 24/28] Added more units for harvests --- app/helpers/harvests_helper.rb | 4 ++-- app/models/harvest.rb | 10 +++++++++- spec/models/harvest_spec.rb | 6 +++--- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/app/helpers/harvests_helper.rb b/app/helpers/harvests_helper.rb index a6078dc60..b5f335db9 100644 --- a/app/helpers/harvests_helper.rb +++ b/app/helpers/harvests_helper.rb @@ -17,9 +17,9 @@ module HarvestsHelper def display_human_quantity(harvest) if ! harvest.quantity.blank? && harvest.quantity > 0 - if harvest.unit == 'individual' + if harvest.unit == 'individual' # just the number number_to_human(harvest.quantity, :strip_insignificant_zeros => true) - elsif harvest.unit == 'bunch' + elsif ! harvest.unit.blank? # pluralize anything else return pluralize(number_to_human(harvest.quantity, :strip_insignificant_zeros => true), harvest.unit) else return "#{number_to_human(harvest.quantity, :strip_insignificant_zeros => true)} #{harvest.unit}" diff --git a/app/models/harvest.rb b/app/models/harvest.rb index 165655b55..ec5b2c5cc 100644 --- a/app/models/harvest.rb +++ b/app/models/harvest.rb @@ -14,7 +14,15 @@ class Harvest < ActiveRecord::Base UNITS_VALUES = { "individual" => "individual", - "bunches" => "bunch" + "bunches" => "bunch", + "sprigs" => "sprig", + "handfuls" => "handful", + "litres" => "litre", + "pints" => "ping", + "quarts" => "quart", + "buckets" => "bucket", + "baskets" => "basket", + "bushels" => "bushel" } validates :unit, :inclusion => { :in => UNITS_VALUES.values, :message => "%{value} is not a valid unit" }, diff --git a/spec/models/harvest_spec.rb b/spec/models/harvest_spec.rb index e771f2a13..40497cac0 100644 --- a/spec/models/harvest_spec.rb +++ b/spec/models/harvest_spec.rb @@ -40,9 +40,9 @@ describe Harvest do end context 'units' do - it 'all valid units should work' do - ['individual', 'bunch', nil, ''].each do |s| - @harvest = FactoryGirl.build(:harvest, :unit=> s) + Harvest::UNITS_VALUES.values.push(nil, '').each do |s| + it "#{s} should be a valid unit" do + @harvest = FactoryGirl.build(:harvest, :unit => s) @harvest.should be_valid end end From 294a16391819892a58fe51f20c9f9e2953914068 Mon Sep 17 00:00:00 2001 From: Skud Date: Tue, 1 Oct 2013 12:37:03 +1000 Subject: [PATCH 25/28] Removed duplicate edit buttons --- app/views/harvests/show.html.haml | 3 --- app/views/plantings/show.html.haml | 3 --- 2 files changed, 6 deletions(-) diff --git a/app/views/harvests/show.html.haml b/app/views/harvests/show.html.haml index b3ccbd866..a0920dc5a 100644 --- a/app/views/harvests/show.html.haml +++ b/app/views/harvests/show.html.haml @@ -23,6 +23,3 @@ :markdown #{ @harvest.description != "" ? @harvest.description : "No description given." } - -- if can? :edit, @harvest - = link_to 'Edit', edit_harvest_path(@harvest), :class => 'btn btn-mini' diff --git a/app/views/plantings/show.html.haml b/app/views/plantings/show.html.haml index a192a27d0..9c99fca21 100644 --- a/app/views/plantings/show.html.haml +++ b/app/views/plantings/show.html.haml @@ -41,9 +41,6 @@ :markdown #{ @planting.description != "" ? @planting.description : "No description given." } -- if can? :edit, @planting - = link_to 'Edit', edit_planting_path(@planting), :class => 'btn btn-mini' - - if @planting.photos.count > 0 or (can? :edit, @planting and can? :create, Photo) %h2 Pictures From 97065314f25b863ec8fe7c0df98c049460b86ece Mon Sep 17 00:00:00 2001 From: Skud Date: Tue, 1 Oct 2013 12:43:01 +1000 Subject: [PATCH 26/28] Fixed bug in "all test1's seeds" link and added similar links to plantings and harvests --- app/views/harvests/show.html.haml | 5 +++++ app/views/plantings/show.html.haml | 5 +++++ app/views/seeds/show.html.haml | 2 +- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/app/views/harvests/show.html.haml b/app/views/harvests/show.html.haml index a0920dc5a..62017fd21 100644 --- a/app/views/harvests/show.html.haml +++ b/app/views/harvests/show.html.haml @@ -2,6 +2,11 @@ .row-fluid .span6 + %p + %b Owner: + = link_to @harvest.owner, @harvest.owner + — + = link_to "view all #{@harvest.owner}'s harvests", harvests_by_owner_path(:owner => @harvest.owner.slug) %p %b Harvested: = @harvest.harvested_at ? @harvest.harvested_at : "not specified" diff --git a/app/views/plantings/show.html.haml b/app/views/plantings/show.html.haml index 9c99fca21..b0120a569 100644 --- a/app/views/plantings/show.html.haml +++ b/app/views/plantings/show.html.haml @@ -2,6 +2,11 @@ .row-fluid .span6 + %p + %b Owner: + = link_to @planting.owner, @planting.owner + — + = link_to "view all #{@planting.owner}'s plantings", plantings_by_owner_path(:owner => @planting.owner.slug) %p %b Planted: = @planting.planted_at ? @planting.planted_at : "not specified" diff --git a/app/views/seeds/show.html.haml b/app/views/seeds/show.html.haml index a24c01e40..7bfa6e992 100644 --- a/app/views/seeds/show.html.haml +++ b/app/views/seeds/show.html.haml @@ -6,7 +6,7 @@ %b Owner: = link_to @seed.owner, @seed.owner — - = link_to "view all #{@seed.owner}'s seeds", seeds_path(:owner_id => @seed.owner.id) + = link_to "view all #{@seed.owner}'s seeds", seeds_by_owner_path(:owner => @seed.owner.slug) %p %b Quantity: = @seed.quantity.blank? ? "not specified" : @seed.quantity From 7d2cadce839d2165a355c896539348b833401396 Mon Sep 17 00:00:00 2001 From: Skud Date: Wed, 2 Oct 2013 10:18:23 +1000 Subject: [PATCH 27/28] Added 'harvest this' link to crop page --- app/views/crops/show.html.haml | 3 +++ spec/views/crops/show.html.haml_spec.rb | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/app/views/crops/show.html.haml b/app/views/crops/show.html.haml index 952d6c5e4..cd6e8adce 100644 --- a/app/views/crops/show.html.haml +++ b/app/views/crops/show.html.haml @@ -22,6 +22,9 @@ - else = render :partial => 'shared/signin_signup', :locals => { :to => 'plant this crop' } + - if can? :create, Harvest + = link_to "Harvest this", new_harvest_path(:crop_id => @crop.id), :class => 'btn btn-primary' + - if can? :create, Seed = link_to 'Add seeds to stash', new_seed_path(:params => { :crop_id => @crop.id }), :class => 'btn btn-primary' diff --git a/spec/views/crops/show.html.haml_spec.rb b/spec/views/crops/show.html.haml_spec.rb index dd79a443a..84795fa05 100644 --- a/spec/views/crops/show.html.haml_spec.rb +++ b/spec/views/crops/show.html.haml_spec.rb @@ -187,6 +187,10 @@ describe "crops/show" do rendered.should contain "Plant this" end + it "shows a harvest this button" do + rendered.should contain "Harvest this" + end + it "links to the right crop in the planting link" do assert_select("a[href=#{new_planting_path}?crop_id=#{@crop.id}]") end From 3f7160557240d9b0c0642279ada14bcb54393678 Mon Sep 17 00:00:00 2001 From: Skud Date: Wed, 2 Oct 2013 10:29:45 +1000 Subject: [PATCH 28/28] Turned quick links on homepage into buttons --- app/views/home/index.html.haml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/app/views/home/index.html.haml b/app/views/home/index.html.haml index 7753ddba9..d98bcc4a0 100644 --- a/app/views/home/index.html.haml +++ b/app/views/home/index.html.haml @@ -7,14 +7,13 @@ = Growstuff::Application.config.site_name = current_member = render :partial => 'stats' - %ul.inline - %li{ :style => 'padding-left: 0px' } - %strong Quick links: - %li= link_to "Plant something", new_planting_path - %li= link_to "Harvest something", new_harvest_path - %li= link_to "Add seeds", new_seed_path - %li= link_to "Post", new_post_path - %li= link_to "Edit profile", edit_member_registration_path + %p + .btn-group + = link_to "Plant", new_planting_path, :class => 'btn' + = link_to "Harvest", new_harvest_path, :class => 'btn' + = link_to "Add seeds", new_seed_path, :class => 'btn' + = link_to "Post", new_post_path, :class => 'btn' + = link_to "Edit profile", edit_member_registration_path, :class => 'btn' - else .visible-desktop.visible-tablet