From af87c9db473e8db354cb13b6b2c630d97514b827 Mon Sep 17 00:00:00 2001 From: Miles Gould Date: Sun, 19 Oct 2014 17:15:22 +0100 Subject: [PATCH 01/38] Remove debugger gem It wouldn't install under Ruby 2.1.2, and we weren't using it anyway. --- Gemfile | 3 --- Gemfile.lock | 8 -------- 2 files changed, 11 deletions(-) diff --git a/Gemfile b/Gemfile index 2360041eb..124c1f4f9 100644 --- a/Gemfile +++ b/Gemfile @@ -80,9 +80,6 @@ gem 'flickraw' # To use debugger group :development do - # Installation of the debugger gem fails on Travis CI, - # so we don't use it in the test environment - gem 'debugger' # A debugger and irb alternative. Pry doesn't play nice # with unicorn, so start a Webrick server when debugging # with Pry diff --git a/Gemfile.lock b/Gemfile.lock index fae16d6ad..6f6b7d1a5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -77,7 +77,6 @@ GEM coffee-script-source execjs coffee-script-source (1.8.0) - columnize (0.8.9) commonjs (0.2.7) compass (0.12.7) chunky_png (~> 1.2) @@ -96,12 +95,6 @@ GEM dalli (2.7.2) database_cleaner (1.3.0) debug_inspector (0.0.2) - debugger (1.6.8) - columnize (>= 0.3.1) - debugger-linecache (~> 1.2.0) - debugger-ruby_core_source (~> 1.3.5) - debugger-linecache (1.2.0) - debugger-ruby_core_source (1.3.5) devise (3.2.4) bcrypt (~> 3.0) orm_adapter (~> 0.1) @@ -336,7 +329,6 @@ DEPENDENCIES csv_shaper dalli database_cleaner (~> 1.3.0) - debugger devise (~> 3.2.0) factory_girl_rails (~> 4.0) figaro From 3d105533737306174fa2f1b8f2678ce402ded436 Mon Sep 17 00:00:00 2001 From: Miles Gould Date: Sun, 19 Oct 2014 17:16:04 +0100 Subject: [PATCH 02/38] Add Rake task to load altnames. --- lib/tasks/growstuff.rake | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/lib/tasks/growstuff.rake b/lib/tasks/growstuff.rake index f19bf1fed..0e0555949 100644 --- a/lib/tasks/growstuff.rake +++ b/lib/tasks/growstuff.rake @@ -270,6 +270,36 @@ namespace :growstuff do p.save end end + + desc "October 2014: add alternate names for crops" + task :add_alternate_names_for_crops => :environment do + require 'csv' + @file = ENV['file'] or raise "Usage: rake growstuff:oneoff:add_alternate_names_for_crops file=file.csv" + puts "Loading alternate names from #{@file}..." + cropbot = Member.find_by_login_name("cropbot") + CSV.foreach(@file) do |row| + crop_id, crop_name, alternate_names = row + if crop_name.blank? or alternate_names.blank? then + next + end + crop = Crop.find_by_name(crop_name) + if crop.nil? then + puts "Couldn't find crop #{crop_name}" + next + end + if crop.id.to_s != crop_id then + puts "crop #{crop} has ID #{crop.id}, expected #{crop_id}" + end + alternate_names.split(/,\s*/).each do |an| + puts "Adding alternate name '#{an}' to #{crop}" + AlternateName.create( + name: an, + crop_id: crop.id, + creator_id: cropbot.id + ) + end + end + end end # end oneoff section end From 0aea1721d82159bd76c4ec104bc911adbfbf443e Mon Sep 17 00:00:00 2001 From: Miles Gould Date: Sun, 19 Oct 2014 17:22:34 +0100 Subject: [PATCH 03/38] Add altname data and include load in deploy-tasks. --- db/seeds/alternate_names_201410.csv | 383 ++++++++++++++++++++++++++++ lib/tasks/growstuff.rake | 4 +- script/deploy-tasks.sh | 3 + 3 files changed, 388 insertions(+), 2 deletions(-) create mode 100644 db/seeds/alternate_names_201410.csv diff --git a/db/seeds/alternate_names_201410.csv b/db/seeds/alternate_names_201410.csv new file mode 100644 index 000000000..0430b5c2d --- /dev/null +++ b/db/seeds/alternate_names_201410.csv @@ -0,0 +1,383 @@ +Id,Name,Alternate names (comma separated) +1,achiote,"aploppas, uruku" +2,ackee,"achee, ackee apple, akee" +267,acorn squash,"pepper squash, Des Moines squash" +3,acuyo,"yerba santa, hierba santa, Mexican pepperleaf, tlanepa, anisillo, root beer plant, sacred pepper" +345,adjuma pepper,"adjoema, ojemma, aji umba" +346,ají dulce pepper, +312,Aleppo pepper, +4,alexanders,"alisanders, horse parsley, smyrnium" +5,alfalfa,lucerne +6,allspice,"Jamaica pepper, pepper, myrtle pepper, pimenta, pimento, English pepper, newspice" +7,almond, +254,aloe vera, +8,amaranth, +313,Anaheim pepper,New Mexico pepper +9,anise,aniseed +10,apple, +11,apple mint, +12,apricot, +13,arrowroot,"maranta, West Indian arrowroot, obedience plant, Bermuda arrowroot, araru, ararao, hulankeeriya" +14,artichoke, +15,arugula,"salad rocket, rucola, rucoli, rugula, colewort, roquette" +16,asparagus, +17,avocado, +271,bamboo, +18,banana, +314,banana pepper,"yellow wax pepper, banana chili" +19,barley, +20,basil,sweet basil +21,bay,"bay laurel, sweet bay, bay, true laurel, Grecian laurel,[1] laurel tree, laurel" +22,bean, +23,beet,"beetroot, table beet, garden beet, red beet, golden beet" +24,bell pepper,"sweet pepper, pepper, capsicum" +353,bhut jolokia pepper,"ghost pepper, ghost chili pepper, red naga chilli, ghost chilli" +241,bilberry,"common bilberry, blue whortleberry, whortleberry, European blueberry, blaeberry, hurtleberry, huckleberry, winberry, fraughan" +315,bird's eye chili,"bird's chili, Thai chili" +340,bishop's crown pepper,"Christmas bell pepper, peri peri, joker's hat pepper" +25,bitter melon,"bitter gourd, bitter squash, goya, karela" +351,black habanero pepper, +248,black mint,"southern cone marigold, stinking roger" +371,black-eyed pea,black-eyed bean +26,blackberry, +27,blackcurrant, +240,blueberry, +236,bok choy,Chinese cabbage +28,borage,starflower +270,brassica, +343,Brazilian starfish, +29,breadfruit, +30,broccoli, +31,Brussels sprout, +32,buckwheat, +286,burdock,"greater burdock, gobō,edible burdock, lappa, beggar's buttons" +265,butternut squash,butternut pumpkin +33,cabbage, +355,cachucha pepper,"Boabs Bonnet, Scotty Bons, Bonney peppers, Caribbean red peppers" +273,cantaloupe,"cantelope, cantaloup, muskmelon, mushmelon, rockmelon, sweet melon, Persian melon, spanspek" +34,cape gooseberry,"Cape gooseberry, Inca berry, Aztec berry, golden berry, giant ground cherry, African ground cherry, Peruvian groundcherry, Peruvian cherry, love-in-a-cage, physalis" +35,caper,Flinders rose +306,Capsicum, +307,Capsicum annuum, +308,Capsicum baccatum, +309,Capsicum chinense,yellow lantern chili +311,Capsicum frutescens, +36,cardoon,"artichoke thistle, cardone, cardoni, carduni, cardi" +37,carrot, +316,cascabel chili,rattle chili +38,cassava,"manioc, yuca, mandioca, tapioca-root, kappa, manioc root" +39,catnip,"catswort, catmint" +40,cauliflower, +264,cavalo nero, borecole +41,cayenne pepper,"Guinea spice, cow-horn pepper, aleva, bird pepper, red pepper" +42,celeriac," turnip-rooted celery, knob celery, celery root" +43,celery, +374,celtuce,"stem lettuce, celery lettuce, asparagus lettuce, Chinese lettuce" +44,chamomile,"camomile, German chamomile, Hungarian chamomile, wild chamomile, scented mayweed" +244,chard,"Swiss chard, silverbeet, crab beet, bright lights, seakale beet, mangold" +45,chaya,tree spinach +46,chayote,"christophene, christophine, cho-cho, mirliton, merleton, chuchu, pear squash, vegetable pear, chouchoute, choko, ishkus, chowchow" +47,cherry, +48,chervil,"garden chervil, French parsley" +49,chestnut, +50,chickpeas,"garbanzo, garbanzo bean, ceci, cece, channa, Bengal gram" +51,chickweed,stitchwort +52,chicory, +321,chile de árbol pepper,"bird's beak chile, rat's tail chile" +318,chiltepin pepper,"chiltepin, chiltepe, chile tepin, turkey, bird’s eye, bird peppers" +53,chinese cabbage,"napa cabbage, bok choy" +54,chives, +237,choy sum,"choi sum, Chinese flowering cabbage" +319,Chungyang red pepper, +55,cicely,sweet cicely +56,citron, +57,coconut, +232,coffee, +58,collard greens,Dalmatian cabbage +59,comfrey,comphrey +304,common mushroom,"button mushroom, white mushroom, cultivated mushroom, table mushroom, champignon mushroom, Swiss brown mushroom, Roman brown mushroom, Italian brown, Italian mushroom, cremini mushroom, crimini mushroom, brown cap mushroom, chestnut mushroom, portobello mushroom" +60,coriander,"cilantro, Chinese parsley, dhania" +61,corn,maize +62,corn salad,"lamb's lettuce, fetticus, nut lettuce, field salad, rapunzel" +372,cowpea, +63,cress,"mustard and cress, garden pepper cress, pepperwort, pepper grass, poor man's pepper" +320,cubanelle pepper,Cuban pepper +261,cucamelon,"mouse melon, Mexican sour gherkin, cucamelon, Mexican miniature watermelon, Mexican sour cucumber" +64,cucumber, +65,cumin,jeera +66,cumquat,kumquat +67,curry leaf, +68,curry plant, +69,daikon,"daikon radish, mooli, white radish, winter radish, Oriental radish, long white radish, Japanese radish, Chinese white radish" +70,dandelion, +71,dates, +347,datil pepper, +72,desert lime, +73,dill, +74,dog rose, +322,dundicut, +75,durian, +76,eggplant,"aubergine, melongene, garden egg, guinea squash" +77,elderberry,"elder, black elder, European elder, European elderberry, European black elderberry" +249,elecampane,"horse-heal, elfdock" +78,endive, +79,epazote,"wormseed, Jesuit's tea, Mexican tea" +323,facing heaven pepper, +348,fatalii pepper, +80,fava bean,"broad bean, fava bean, field bean, bell bean, tic bean" +81,feijoa,"pineapple guava, guavasteen" +82,fennel, +83,fenugreek,methi +84,fiddlehead,fiddlehead greens +85,fig, +86,flax,linseed +324,Fresno pepper, +366,fuzzy kiwifruit, +87,garlic, +88,garlic chives,"Chinese chives, Oriental garlic, Chinese leek, kow choi, gau choy, nira" +89,ginger, +285,goji,wolfberry +367,golden kiwifruit, +364,Good King Henry,"poor-man's asparagus, perennial goosefoot, Lincolnshire spinach, markery" +90,gooseberry, +91,grapefruit, +92,grapes, +325,guajillo pepper, +93,guava, +326,Guntur Sannam chili, +94,habanero, +350,habanero pepper, +358,Hainan yellow lantern,yellow emperor chili +368,hardy kiwifruit,"kiwi berry, arctic kiwi, baby kiwi, dessert kiwi, grape kiwi, northern kiwi, cocktail kiwi" +369,hazelnut,"cobnut, filbert nut" +95,hibiscus,rose mallow +275,honeydew melon, +253,hops, +96,horseradish, +327,Hungarian wax pepper, +283,ice plant,"highway ice plant, pigface, Hottentot fig, sour fig" +328,Italian sweet pepper, +329,jalapeño pepper, +97,jasmine, +98,Jerusalem artichoke,"sunroot, sunchoke, earth apple, topinambour" +99,jicama,"Mexican yam, Mexican turnip" +100,juniper berry, +268,kabocha,"danhobak, fak thong, Japanese pumpkin, kabocha squash" +101,kaffir lime,makrut lime +102,kale, +363,kambuzi, +103,kava, +365,kiwifruit,"kiwi, Chinese gooseberry" +104,kohlrabi,"German turnip, turnip cabbage" +250,lady's bedstraw,yellow bedstraw +259,land cress,"American cress, bank cress, black wood cress, Belle Isle cress, Bermuda cress, early yellowrocket, early wintercress, scurvy cress, creasy greens, upland cress" +105,lavender, +106,leek, +107,lemon, +108,lemon balm,"balm, balm mint" +341,lemon drop pepper,hot lemon pepper +109,lemon myrtle,"lemon myrtle, lemon scented myrtle, lemon scented ironwood, sweet verbena tree, sweet verbena myrtle, lemon scented verbena, lemon scented backhousia" +110,lemon verbena,lemon beebrush +111,lemongrass,"barbed wire grass, silky heads, citronella grass, fever grass" +112,lentils, +113,lettuce, +114,licorice,liquorice +115,lillipilli,"riberry, small leaved lilly pilly, cherry satinash, cherry alder, clove lilli pilli" +116,lima bean,butter bean +117,lime, +238,loquat,"Japanese medlar, Japanese plum, Chinese plum" +118,lovage, +119,luffa,loofah +287,lupin,lupine +120,lupin bean,lupini bean +121,macadamia,"Queensland nut, bush nut, maroochi nut, bauple nut, Hawaii nut" +349,Madame Jeanette pepper,Suriname yellow pepper +122,Malabar spinach,"pui, vine spinach, red vine spinach, climbing spinach, creeping spinach, buffalo spinach, malabar spinach, ceylon spinach" +361,malagueta pepper,"malaguetinha pepper, piri piri pepper" +123,mandarin,"mandarin orange, mandarine" +124,mango, +125,maracuja,"passion fruit, passionfruit, purple granadilla" +126,marjoram,"sweet marjoram, knotted marjoram" +127,marshmallow,"marsh mallow, common marshmallow" +128,medlar,common medlar +331,medusa pepper, +129,melon, +252,Mexican tarragon,"yerbaniz, Mexican marigold, Mexican mint marigold, Mexican tarragon, Spanish tarragon, Texas tarragon" +257,Meyer lemon, +292,midgen berry,midyim +276,milkweed, +130,miner's lettuce,"spring beauty, winter purslane, Indian lettuce" +131,mint,"spearmint, spear mint" +235,mizuna,"shui cai, kyona, Japanese mustard, potherb mustard, Japanese greens, California peppergrass, spider mustard" +279,moringa, +332,mulato pepper, +234,mulberry, +132,mung bean,"moong bean, green gram, golden gram" +284,murnong,yam daisy +303,mushroom, +274,muskmelon, +133,mustard, +375,myoga ginger,Japanese ginger +298,naranjilla,lulo +134,nasturtium, +277,native ginger, +290,nectarine, +246,nettle, +135,New Zealand spinach, +136,nigella," fennel flower, nutmeg flower, black caraway, Roman coriander" +137,oats, +289,Okinawan spinach,edible gynura +138,okra,"ladies' fingers, bhindi, bamia, gumbo" +139,olive, +302,olive herb,holy flax +140,onion,"bulb onion, common onion" +141,orange,sweet orange +142,oregano,wild marjoram +297,pandan,pandan leaves +143,parsley, +144,parsnip, +317,pasilla pepper,"chile negro, chilaca" +145,passion fruit,"passionfruit, purple granadilla" +269,patty-pan squash,"scallop squash, sunburst squash, granny squash, custard marrow, custard squash, white squash, scallopini, schwoughksie squash" +146,pea, +147,peach, +149,peanut,groundnut +150,pear, +151,pearl millet,"cattail millet, candle millet, dark millet" +152,pecan, +334,peperoncini pepper, +342,peppadew pepper, +153,peppermint, +335,pequin pepper,piquin pepper +291,perilla, +263,perpetual spinach,spinach beet +154,Persian lime,"shiraz limoo,Tahiti lime, Bearss lime" +155,persimmon, +333,peter pepper, +156,pigeon pea,"kardis, gandule bean, tropical green pea, kadios, Congo pea, gungo pea, gunga pea, no-eye pea" +157,pigface,angular sea-fig +336,pimento pepper,"pimiento pepper, cherry pepper" +158,pineapple, +359,piri-piri pepper,"peri peri, pili pili, African bird's eye chili" +159,pistachio, +160,plantain,cooking plaintain +161,plum, +337,poblano pepper,"ancho pepper, ancho chile pepper" +162,pomegranate, +163,pomelo,"shaddock, pummelo, pommelo, lusho fruit" +247,pot marigold,"ruddles, common marigold, garden marigold, English marigold, Scottish marigold" +164,potato, +165,prickly pear, +166,pumpkin, +167,purslane,"common purslane, verdolaga, pigweed, little hogweed, red root, pursley, moss rose" +168,quandong,"desert quandong, native peach" +169,quince, +170,quinoa, +171,radicchio,Italian chicory +172,radish, +262,rainbow chard, +173,rapeseed,"rape, oilseed rape, rapa, rappi, rapaseed" +243,rapini,"broccoli raab, broccoli rabe" +174,raspberry,"red raspberry, European raspberry" +352,red savino pepper, +293,redcurrant,red currant +175,rhubarb, +176,rice, +177,rice bean,ricebean +310,rocoto,"rukutu, ruqutu, luqutu" +370,romaine lettuce,cos lettuce +178,rose, +255,rose geranium,"rose geranium, old fashioned rose geranium, rose-scent geranium" +179,roselle,"rosella, rosella fruit, carcade, " +180,rosemary,anthos +281,ruby saltbush,barrier saltbush +181,rue,"common rue, herb-of-grace" +182,runner bean,"scarlet runner bean, multiflora bean" +183,rutabaga,"swede, turnip, yellow turnip, neep" +184,rye, +185,safflower, +186,saffron, +187,sage,"garden sage, common sage" +188,salad burnet,"garden burnet, small burnet, burnet" +189,salsify, +190,samphire,"rock samphire, sea fennel" +338,Santa Fe Grande pepper,"yellow hot chili pepper, guero chili pepper" +191,sassafras,"white sassafras, red sassafras, silky sassafras" +295,scallion,"green onion, spring onion, salad onion, table onion, green shallot, onion stick, long onion, baby onion, precious onion, yard onion, gibbon, syboe, scally onion" +354,Scotch bonnet pepper,"Boabs bonnet, Scotty bons, bonney peppers, Caribbean red peppers" +339,serrano pepper, +192,sesame, +193,shallot, +305,shiitake,"Sawtooth oak mushroom, black forest mushroom, black mushroom, golden oak mushroom, oakwood mushroom" +330,shishito pepper, +362,siling labuyo pepper, +373,snap pea,"sugar snap peas, mangetout" +260,snow pea,mangetout +194,sorghum, +195,sorrel,"common sorrel, garden sorrel, spinach dock, narrow-leaved dock" +196,soursop,Brazilian pawpaw +197,soybean,soya bean +266,spaghetti squash,"vegetable spaghetti, noodle squash, vegetable marrow, spaghetti marrow, squaghetti" +198,spearmint,spear mint +199,spinach, +251,squash, +200,star anise,"star aniseed, Chinese star anise" +201,starfruit,carambola +202,stevia, +203,strawberry,garden strawberry +204,summer savory, +205,sunflower, +206,sweet potato,kumara +207,Swiss chard,chard +360,Tabasco pepper, +208,tamarillo,"tree tomato, tamamoro" +209,tamarind, +210,tangerine, +211,tansy,"common tansy, bitter buttons, cow bitter, mugwort, golden buttons" +212,taro, +213,tarragon, +242,tatsoi,"spinach mustard, spoon mustard, rosette bok choy" +233,tea, +214,thyme, +215,tomatillo,"husk tomato, mexican husk tomato" +216,tomato, +357,Trinidad Moruga scorpion pepper, +356,Trinidad scorpion butch T pepper, +217,turmeric, +218,turnip,white turnip +219,urad bean,"urad dal, black gram, black lentil, white lentil, black matpe bean" +220,valerian,"garden valerian, garden heliotrope, all-heal" +221,vanilla, +239,Vietnamese mint,"Vietnamese mint, Vietnamese cilantro, Cambodian mint, hot mint" +222,walnut, +223,wasabi,Japanese horseradish +301,water caltrop,"water caltrop, water chestnut, buffalo nut, bat nut, devil pod, ling nut" +300,water chestnut,Chinese water chestnut +299,watercress, +224,watermelon, +282,wattle,"acacia, thorntree, whistling thorn" +296,Welsh onion,"Welsh onion, Japanese bunching onion, green onion, spring onion, scallion, escallion, salad onion" +225,wheat, +294,white currant, +344,wild baccatum, +278,wild ginger,"British Columbia wild ginger, western wild ginger, long-tailed wild ginger" +376,wine cap mushroom,"burgundy mushroom, king stropharia, godzilla mushroom" +280,winged bean,"Goa bean, asparagus pea, four-angled bean, four-cornered bean, Manila bean, Mauritius bean, winged pea" +256,winter melon,"white gourd, winter gourd, tallow gourd, Chinese preserving melon, ash gourd" +226,winter savory, +258,wood sorrel,"yellow sorrel, pink sorrel" +227,wormwood,"absinthium, absinthe wormwood, common wormwood, green ginger, grand wormwood" +228,yam, +229,yardlong bean,"yardlong bean, bora, bodi, long-podded cowpea, asparagus bean, pea bean, snake bean, Chinese long bean" +230,yarrow,"common yarrow, gordaldo, nosebleed plant, old man's pepper, devil's nettle, sanguinary, milfoil, soldier's woundwort, thousand-leaf, thousand-seal" +231,zucchini,"courgette, baby marrow" +,Slender Amaranth,Green Amaranth +,Red Amaranth,"Huautli, Alegría, Blood amaranth, red amaranth, purple amaranth, prince's feather, Mexican grain amaranth, shravani maath, rajgira" +,Red Spinach,"Red spinach, Chinese spinach, Spleen Amaranth, Hon-toi-moi, Yin choy, Hsien tsai." +,Common bean,"common bean, string bean, field bean, flageolet bean, French bean, garden bean, haricot bean, pop bean, snap bean" +,Smooth Amaranth,"Smooth pigweed, red amaranth, slim amaranth" +,Prince of Wales," Prince-of-Wales feather, Prince's feather" +,Palmers Amaranth,"Palmer amaranth, Palmer's pigweed, carelessweed" +,Red-Root Amaranth,"redroot pigweed, red-rooted pigweed, common amaranth, pigweed amaranth, common tumbleweed" +,Spiny Amaranth,"prickly amaranth, thorny amaranth" +,Tandaljo,"Tandalja bhaji, callaloo, Joseph's coat " \ No newline at end of file diff --git a/lib/tasks/growstuff.rake b/lib/tasks/growstuff.rake index 0e0555949..288c5ff62 100644 --- a/lib/tasks/growstuff.rake +++ b/lib/tasks/growstuff.rake @@ -272,9 +272,9 @@ namespace :growstuff do end desc "October 2014: add alternate names for crops" - task :add_alternate_names_for_crops => :environment do + task :add_alternate_names => :environment do require 'csv' - @file = ENV['file'] or raise "Usage: rake growstuff:oneoff:add_alternate_names_for_crops file=file.csv" + @file = ENV['file'] or raise "Usage: rake growstuff:oneoff:add_alternate_names file=file.csv" puts "Loading alternate names from #{@file}..." cropbot = Member.find_by_login_name("cropbot") CSV.foreach(@file) do |row| diff --git a/script/deploy-tasks.sh b/script/deploy-tasks.sh index 451fe0032..5b930b551 100755 --- a/script/deploy-tasks.sh +++ b/script/deploy-tasks.sh @@ -18,3 +18,6 @@ rake growstuff:oneoff:remove_unused_photos echo "2014-10-05 - generate crops_posts records for existing posts" rake growstuff:oneoff:generate_crops_posts_records + +echo "2014-10-19 - load alternate names for crops" +rake growstuff:oneoff:add_alternate_names file=db/seeds/alternate_names_201410.csv From 36be5e9533874e035c7e032581ee16df2d6dd3e8 Mon Sep 17 00:00:00 2001 From: Miles Gould Date: Sun, 19 Oct 2014 21:54:46 +0100 Subject: [PATCH 04/38] Hardcode alternate-name CSV file path. --- lib/tasks/growstuff.rake | 6 +++--- script/deploy-tasks.sh | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/tasks/growstuff.rake b/lib/tasks/growstuff.rake index 288c5ff62..c702052c9 100644 --- a/lib/tasks/growstuff.rake +++ b/lib/tasks/growstuff.rake @@ -274,10 +274,10 @@ namespace :growstuff do desc "October 2014: add alternate names for crops" task :add_alternate_names => :environment do require 'csv' - @file = ENV['file'] or raise "Usage: rake growstuff:oneoff:add_alternate_names file=file.csv" - puts "Loading alternate names from #{@file}..." + file = "db/seeds/alternate_names_201410.csv" + puts "Loading alternate names from #{file}..." cropbot = Member.find_by_login_name("cropbot") - CSV.foreach(@file) do |row| + CSV.foreach(file) do |row| crop_id, crop_name, alternate_names = row if crop_name.blank? or alternate_names.blank? then next diff --git a/script/deploy-tasks.sh b/script/deploy-tasks.sh index 5b930b551..715e9dfb8 100755 --- a/script/deploy-tasks.sh +++ b/script/deploy-tasks.sh @@ -20,4 +20,4 @@ echo "2014-10-05 - generate crops_posts records for existing posts" rake growstuff:oneoff:generate_crops_posts_records echo "2014-10-19 - load alternate names for crops" -rake growstuff:oneoff:add_alternate_names file=db/seeds/alternate_names_201410.csv +rake growstuff:oneoff:add_alternate_names From 06a4fcab712072da3e42509752fe871ec0d32748 Mon Sep 17 00:00:00 2001 From: Miles Gould Date: Sun, 19 Oct 2014 22:19:41 +0100 Subject: [PATCH 05/38] Remove superfluous* error-checks from load_altnames * /me crosses fingers... --- db/seeds/alternate_names_201410.csv | 3 +-- lib/tasks/growstuff.rake | 12 ++---------- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/db/seeds/alternate_names_201410.csv b/db/seeds/alternate_names_201410.csv index 0430b5c2d..2a48911c1 100644 --- a/db/seeds/alternate_names_201410.csv +++ b/db/seeds/alternate_names_201410.csv @@ -1,4 +1,3 @@ -Id,Name,Alternate names (comma separated) 1,achiote,"aploppas, uruku" 2,ackee,"achee, ackee apple, akee" 267,acorn squash,"pepper squash, Des Moines squash" @@ -380,4 +379,4 @@ Id,Name,Alternate names (comma separated) ,Palmers Amaranth,"Palmer amaranth, Palmer's pigweed, carelessweed" ,Red-Root Amaranth,"redroot pigweed, red-rooted pigweed, common amaranth, pigweed amaranth, common tumbleweed" ,Spiny Amaranth,"prickly amaranth, thorny amaranth" -,Tandaljo,"Tandalja bhaji, callaloo, Joseph's coat " \ No newline at end of file +,Tandaljo,"Tandalja bhaji, callaloo, Joseph's coat " diff --git a/lib/tasks/growstuff.rake b/lib/tasks/growstuff.rake index c702052c9..479fd9f4e 100644 --- a/lib/tasks/growstuff.rake +++ b/lib/tasks/growstuff.rake @@ -279,22 +279,14 @@ namespace :growstuff do cropbot = Member.find_by_login_name("cropbot") CSV.foreach(file) do |row| crop_id, crop_name, alternate_names = row - if crop_name.blank? or alternate_names.blank? then + if alternate_names.blank? then next end - crop = Crop.find_by_name(crop_name) - if crop.nil? then - puts "Couldn't find crop #{crop_name}" - next - end - if crop.id.to_s != crop_id then - puts "crop #{crop} has ID #{crop.id}, expected #{crop_id}" - end alternate_names.split(/,\s*/).each do |an| puts "Adding alternate name '#{an}' to #{crop}" AlternateName.create( name: an, - crop_id: crop.id, + crop_id: crop_id, creator_id: cropbot.id ) end From 7c3059fcae6c492dd09658816fb8f318fafa6aed Mon Sep 17 00:00:00 2001 From: Miles Gould Date: Sun, 19 Oct 2014 22:21:10 +0100 Subject: [PATCH 06/38] Fix typo in altname CSV --- db/seeds/alternate_names_201410.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/seeds/alternate_names_201410.csv b/db/seeds/alternate_names_201410.csv index 2a48911c1..913f9124f 100644 --- a/db/seeds/alternate_names_201410.csv +++ b/db/seeds/alternate_names_201410.csv @@ -26,7 +26,7 @@ 314,banana pepper,"yellow wax pepper, banana chili" 19,barley, 20,basil,sweet basil -21,bay,"bay laurel, sweet bay, bay, true laurel, Grecian laurel,[1] laurel tree, laurel" +21,bay,"bay laurel, sweet bay, bay, true laurel, Grecian laurel, laurel tree, laurel" 22,bean, 23,beet,"beetroot, table beet, garden beet, red beet, golden beet" 24,bell pepper,"sweet pepper, pepper, capsicum" From badb0c4fe7fe60c1e975aac90508c19acf54bc14 Mon Sep 17 00:00:00 2001 From: Miles Gould Date: Sun, 19 Oct 2014 22:21:29 +0100 Subject: [PATCH 07/38] Make load altnames task idempotent. --- lib/tasks/growstuff.rake | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/tasks/growstuff.rake b/lib/tasks/growstuff.rake index 479fd9f4e..11236be4b 100644 --- a/lib/tasks/growstuff.rake +++ b/lib/tasks/growstuff.rake @@ -283,8 +283,7 @@ namespace :growstuff do next end alternate_names.split(/,\s*/).each do |an| - puts "Adding alternate name '#{an}' to #{crop}" - AlternateName.create( + AlternateName.find_or_create( name: an, crop_id: crop_id, creator_id: cropbot.id From f795918e17fa0b8047d4f93c0a1d4d0da405ca5d Mon Sep 17 00:00:00 2001 From: Miles Gould Date: Sun, 19 Oct 2014 22:49:18 +0100 Subject: [PATCH 08/38] Remove alternate names for crops without IDs. --- db/seeds/alternate_names_201410.csv | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/db/seeds/alternate_names_201410.csv b/db/seeds/alternate_names_201410.csv index 913f9124f..e606482ee 100644 --- a/db/seeds/alternate_names_201410.csv +++ b/db/seeds/alternate_names_201410.csv @@ -355,7 +355,7 @@ 299,watercress, 224,watermelon, 282,wattle,"acacia, thorntree, whistling thorn" -296,Welsh onion,"Welsh onion, Japanese bunching onion, green onion, spring onion, scallion, escallion, salad onion" +296,Welsh onion,"Japanese bunching onion, green onion, spring onion, scallion, escallion, salad onion" 225,wheat, 294,white currant, 344,wild baccatum, @@ -369,14 +369,4 @@ 228,yam, 229,yardlong bean,"yardlong bean, bora, bodi, long-podded cowpea, asparagus bean, pea bean, snake bean, Chinese long bean" 230,yarrow,"common yarrow, gordaldo, nosebleed plant, old man's pepper, devil's nettle, sanguinary, milfoil, soldier's woundwort, thousand-leaf, thousand-seal" -231,zucchini,"courgette, baby marrow" -,Slender Amaranth,Green Amaranth -,Red Amaranth,"Huautli, Alegría, Blood amaranth, red amaranth, purple amaranth, prince's feather, Mexican grain amaranth, shravani maath, rajgira" -,Red Spinach,"Red spinach, Chinese spinach, Spleen Amaranth, Hon-toi-moi, Yin choy, Hsien tsai." -,Common bean,"common bean, string bean, field bean, flageolet bean, French bean, garden bean, haricot bean, pop bean, snap bean" -,Smooth Amaranth,"Smooth pigweed, red amaranth, slim amaranth" -,Prince of Wales," Prince-of-Wales feather, Prince's feather" -,Palmers Amaranth,"Palmer amaranth, Palmer's pigweed, carelessweed" -,Red-Root Amaranth,"redroot pigweed, red-rooted pigweed, common amaranth, pigweed amaranth, common tumbleweed" -,Spiny Amaranth,"prickly amaranth, thorny amaranth" -,Tandaljo,"Tandalja bhaji, callaloo, Joseph's coat " +231,zucchini,"courgette, baby marrow" \ No newline at end of file From a9fdab5d7c931af5e9b5f8369fb8fea61cc7efc4 Mon Sep 17 00:00:00 2001 From: Yoong Kang Lim Date: Wed, 12 Nov 2014 00:23:01 +1100 Subject: [PATCH 09/38] Basic follower relationship --- app/controllers/follows_controller.rb | 27 ++++++++++++++++ app/models/follow.rb | 6 ++++ app/models/member.rb | 6 ++++ app/views/follows/_form.html.haml | 16 ++++++++++ app/views/follows/edit.html.haml | 7 +++++ app/views/follows/index.html.haml | 21 +++++++++++++ app/views/follows/new.html.haml | 5 +++ app/views/follows/show.html.haml | 12 +++++++ config/routes.rb | 2 ++ db/migrate/20141111130849_create_follows.rb | 10 ++++++ db/schema.rb | 9 +++++- spec/factories/follows.rb | 7 +++++ spec/models/follow_spec.rb | 5 +++ spec/requests/follows_spec.rb | 11 +++++++ spec/routing/follows_routing_spec.rb | 35 +++++++++++++++++++++ 15 files changed, 178 insertions(+), 1 deletion(-) create mode 100644 app/controllers/follows_controller.rb create mode 100644 app/models/follow.rb create mode 100644 app/views/follows/_form.html.haml create mode 100644 app/views/follows/edit.html.haml create mode 100644 app/views/follows/index.html.haml create mode 100644 app/views/follows/new.html.haml create mode 100644 app/views/follows/show.html.haml create mode 100644 db/migrate/20141111130849_create_follows.rb create mode 100644 spec/factories/follows.rb create mode 100644 spec/models/follow_spec.rb create mode 100644 spec/requests/follows_spec.rb create mode 100644 spec/routing/follows_routing_spec.rb diff --git a/app/controllers/follows_controller.rb b/app/controllers/follows_controller.rb new file mode 100644 index 000000000..7cb078fd4 --- /dev/null +++ b/app/controllers/follows_controller.rb @@ -0,0 +1,27 @@ +class FollowsController < ApplicationController + + # POST /follows + def create + @follow = current_user.follows.build(followed_id: params[:followed_id]) + + if @follow.save + flash[:notice] = "Followed #{@follow.followed.name}." + redirect_to :back + else + flash[:error] = "Already following or error while following." + redirect_to :back + end + end + + + # DELETE /follows/1 + # DELETE /follows/1.json + def destroy + @follow = current_user.follows.find(params[:id]) + name = @follow.followed.name + @follow.destroy + + flash[:notice] = "Unfollowed #{name}" + redirect_to root_path + end +end diff --git a/app/models/follow.rb b/app/models/follow.rb new file mode 100644 index 000000000..cbac4948f --- /dev/null +++ b/app/models/follow.rb @@ -0,0 +1,6 @@ +class Follow < ActiveRecord::Base + attr_accessible :followed_id, :member_id + belongs_to :member_id + belongs_to :followed, class_name: "Member" + validates :member_id, uniqueness: { scope: :followed_id } +end diff --git a/app/models/member.rb b/app/models/member.rb index 14d16c175..4c1d209d2 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -27,6 +27,12 @@ class Member < ActiveRecord::Base has_many :photos + has_many :follows + has_many :followed, through: :follows + + has_many :inverse_follows, class_name: "Follow", foreign_key: "follower_id" + has_many :followers, through: :inverse_follows, source: :member + default_scope order("lower(login_name) asc") scope :confirmed, where('confirmed_at IS NOT NULL') scope :located, where("location <> '' and latitude IS NOT NULL and longitude IS NOT NULL") diff --git a/app/views/follows/_form.html.haml b/app/views/follows/_form.html.haml new file mode 100644 index 000000000..f11f553f6 --- /dev/null +++ b/app/views/follows/_form.html.haml @@ -0,0 +1,16 @@ += form_for @follow do |f| + - if @follow.errors.any? + #error_explanation + %h2= "#{pluralize(@follow.errors.count, "error")} prohibited this follow from being saved:" + %ul + - @follow.errors.full_messages.each do |msg| + %li= msg + + .field + = f.label :member_id + = f.number_field :member_id + .field + = f.label :followed_id + = f.number_field :followed_id + .actions + = f.submit 'Save' diff --git a/app/views/follows/edit.html.haml b/app/views/follows/edit.html.haml new file mode 100644 index 000000000..9ed5e22d5 --- /dev/null +++ b/app/views/follows/edit.html.haml @@ -0,0 +1,7 @@ +%h1 Editing follow + += render 'form' + += link_to 'Show', @follow +\| += link_to 'Back', follows_path diff --git a/app/views/follows/index.html.haml b/app/views/follows/index.html.haml new file mode 100644 index 000000000..75f9ab0e4 --- /dev/null +++ b/app/views/follows/index.html.haml @@ -0,0 +1,21 @@ +%h1 Listing follows + +%table + %tr + %th Member + %th Followed + %th + %th + %th + + - @follows.each do |follow| + %tr + %td= follow.member_id + %td= follow.followed_id + %td= link_to 'Show', follow + %td= link_to 'Edit', edit_follow_path(follow) + %td= link_to 'Destroy', follow, :method => :delete, :data => { :confirm => 'Are you sure?' } + +%br + += link_to 'New Follow', new_follow_path diff --git a/app/views/follows/new.html.haml b/app/views/follows/new.html.haml new file mode 100644 index 000000000..fce286b48 --- /dev/null +++ b/app/views/follows/new.html.haml @@ -0,0 +1,5 @@ +%h1 New follow + += render 'form' + += link_to 'Back', follows_path diff --git a/app/views/follows/show.html.haml b/app/views/follows/show.html.haml new file mode 100644 index 000000000..ea673e551 --- /dev/null +++ b/app/views/follows/show.html.haml @@ -0,0 +1,12 @@ +%p#notice= notice + +%p + %b Member: + = @follow.member_id +%p + %b Followed: + = @follow.followed_id + += link_to 'Edit', edit_follow_path(@follow) +\| += link_to 'Back', follows_path diff --git a/config/routes.rb b/config/routes.rb index d751647d5..8011d2fe6 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,5 +1,7 @@ Growstuff::Application.routes.draw do + resources :follows + resources :plant_parts devise_for :members, :controllers => { :registrations => "registrations", :passwords => "passwords" } diff --git a/db/migrate/20141111130849_create_follows.rb b/db/migrate/20141111130849_create_follows.rb new file mode 100644 index 000000000..2b9d7f8a9 --- /dev/null +++ b/db/migrate/20141111130849_create_follows.rb @@ -0,0 +1,10 @@ +class CreateFollows < ActiveRecord::Migration + def change + create_table :follows do |t| + t.integer :member_id + t.integer :followed_id + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 39a68cab2..e22a2289b 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 => 20141018111015) do +ActiveRecord::Schema.define(:version => 20141111130849) do create_table "account_types", :force => true do |t| t.string "name", :null => false @@ -80,6 +80,13 @@ ActiveRecord::Schema.define(:version => 20141018111015) do add_index "crops_posts", ["crop_id", "post_id"], :name => "index_crops_posts_on_crop_id_and_post_id" add_index "crops_posts", ["crop_id"], :name => "index_crops_posts_on_crop_id" + create_table "follows", :force => true do |t| + t.integer "member_id" + t.integer "followed_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + create_table "forums", :force => true do |t| t.string "name", :null => false t.text "description", :null => false diff --git a/spec/factories/follows.rb b/spec/factories/follows.rb new file mode 100644 index 000000000..756111732 --- /dev/null +++ b/spec/factories/follows.rb @@ -0,0 +1,7 @@ +FactoryGirl.define do + factory :follow do + member_id 1 +followed_id 1 + end + +end diff --git a/spec/models/follow_spec.rb b/spec/models/follow_spec.rb new file mode 100644 index 000000000..7a7eb0fa5 --- /dev/null +++ b/spec/models/follow_spec.rb @@ -0,0 +1,5 @@ +require 'spec_helper' + +describe Follow do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/requests/follows_spec.rb b/spec/requests/follows_spec.rb new file mode 100644 index 000000000..32a4c2e44 --- /dev/null +++ b/spec/requests/follows_spec.rb @@ -0,0 +1,11 @@ +require 'spec_helper' + +describe "Follows" do + describe "GET /follows" 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 follows_path + response.status.should be(200) + end + end +end diff --git a/spec/routing/follows_routing_spec.rb b/spec/routing/follows_routing_spec.rb new file mode 100644 index 000000000..82ddc7fda --- /dev/null +++ b/spec/routing/follows_routing_spec.rb @@ -0,0 +1,35 @@ +require "spec_helper" + +describe FollowsController do + describe "routing" do + + it "routes to #index" do + get("/follows").should route_to("follows#index") + end + + it "routes to #new" do + get("/follows/new").should route_to("follows#new") + end + + it "routes to #show" do + get("/follows/1").should route_to("follows#show", :id => "1") + end + + it "routes to #edit" do + get("/follows/1/edit").should route_to("follows#edit", :id => "1") + end + + it "routes to #create" do + post("/follows").should route_to("follows#create") + end + + it "routes to #update" do + put("/follows/1").should route_to("follows#update", :id => "1") + end + + it "routes to #destroy" do + delete("/follows/1").should route_to("follows#destroy", :id => "1") + end + + end +end From cacc002a012cfda0651da6ab4d07d6353deb0688 Mon Sep 17 00:00:00 2001 From: Yoong Kang Lim Date: Wed, 12 Nov 2014 01:47:26 +1100 Subject: [PATCH 10/38] Added follow/unfollow buttons --- app/controllers/follows_controller.rb | 9 ++++----- app/controllers/members_controller.rb | 2 +- app/models/follow.rb | 4 ++-- app/models/member.rb | 14 +++++++++++--- app/views/members/show.html.haml | 6 +++++- config/routes.rb | 2 ++ 6 files changed, 25 insertions(+), 12 deletions(-) diff --git a/app/controllers/follows_controller.rb b/app/controllers/follows_controller.rb index 7cb078fd4..b9e07f738 100644 --- a/app/controllers/follows_controller.rb +++ b/app/controllers/follows_controller.rb @@ -2,10 +2,10 @@ class FollowsController < ApplicationController # POST /follows def create - @follow = current_user.follows.build(followed_id: params[:followed_id]) + @follow = current_member.follows.build(:followed_id => params[:followed_id]) if @follow.save - flash[:notice] = "Followed #{@follow.followed.name}." + flash[:notice] = "Followed #{ @follow.followed.login_name }" redirect_to :back else flash[:error] = "Already following or error while following." @@ -17,11 +17,10 @@ class FollowsController < ApplicationController # DELETE /follows/1 # DELETE /follows/1.json def destroy - @follow = current_user.follows.find(params[:id]) - name = @follow.followed.name + @follow = current_member.follows.find(params[:id]) @follow.destroy - flash[:notice] = "Unfollowed #{name}" + flash[:notice] = "Unfollowed #{ @follow.followed.login_name }" redirect_to root_path end end diff --git a/app/controllers/members_controller.rb b/app/controllers/members_controller.rb index 247ac1c8b..08c04a359 100644 --- a/app/controllers/members_controller.rb +++ b/app/controllers/members_controller.rb @@ -23,7 +23,7 @@ class MembersController < ApplicationController # it requires a garden to be passed in @garden. # The new garden is not persisted unless Garden#save is called. @garden = Garden.new - + respond_to do |format| format.html # show.html.haml format.json { render :json => @member.to_json(:only => [:id, :login_name, :bio, :created_at, :slug, :location, :latitude, :longitude]) } diff --git a/app/models/follow.rb b/app/models/follow.rb index cbac4948f..f57f1e76e 100644 --- a/app/models/follow.rb +++ b/app/models/follow.rb @@ -1,6 +1,6 @@ class Follow < ActiveRecord::Base attr_accessible :followed_id, :member_id - belongs_to :member_id + belongs_to :member belongs_to :followed, class_name: "Member" - validates :member_id, uniqueness: { scope: :followed_id } + validates :member_id, uniqueness: { :scope => :followed_id } end diff --git a/app/models/member.rb b/app/models/member.rb index 4c1d209d2..cb3e78fda 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -28,10 +28,10 @@ class Member < ActiveRecord::Base has_many :photos has_many :follows - has_many :followed, through: :follows + has_many :followed, :through => :follows - has_many :inverse_follows, class_name: "Follow", foreign_key: "follower_id" - has_many :followers, through: :inverse_follows, source: :member + has_many :inverse_follows, :class_name => "Follow", :foreign_key => "followed_id" + has_many :followers, :through => :inverse_follows, :source => :member default_scope order("lower(login_name) asc") scope :confirmed, where('confirmed_at IS NOT NULL') @@ -261,4 +261,12 @@ class Member < ActiveRecord::Base }) end + def already_following?(member) + self.follows.exists?(:followed_id => member.id) + end + + def follow_id(member) + self.follows.where(:followed_id => @member.id).first if already_following?(member) + end + end diff --git a/app/views/members/show.html.haml b/app/views/members/show.html.haml index edf4d0b68..bba4afab3 100644 --- a/app/views/members/show.html.haml +++ b/app/views/members/show.html.haml @@ -7,7 +7,11 @@ = link_to "Upgrade account", shop_path, :class => 'btn btn-default' -if can? :create, Notification and current_member != @member =link_to 'Send message', new_notification_path(:recipient_id => @member.id), :class => 'btn btn-default' - + - if current_member != @member && !current_member.already_following?(@member) + = link_to 'Follow', follows_path(:followed_id => @member.id), :method => :post, :class => 'btn btn-default' + - if current_member.already_following?(@member) + - follow = current_member.follows.where(:followed_id => @member.id).first + = link_to 'Unfollow', follow_path(follow), :method => :delete, :class => 'btn btn-default' - content_for :member_rss_login_name, @member.login_name - content_for :member_rss_slug, @member.slug diff --git a/config/routes.rb b/config/routes.rb index 8011d2fe6..a740857ce 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -81,4 +81,6 @@ Growstuff::Application.routes.draw do match '/admin/newsletter' => 'admin#newsletter', :as => :admin_newsletter match '/admin/:action' => 'admin#:action' + + end From 3c3eb1fd785143ee374eb89fddc046689ebaab74 Mon Sep 17 00:00:00 2001 From: Yoong Kang Lim Date: Wed, 12 Nov 2014 01:53:47 +1100 Subject: [PATCH 11/38] Fixed/improved method in member model --- app/models/member.rb | 2 +- app/views/members/show.html.haml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/member.rb b/app/models/member.rb index cb3e78fda..a72dd15a6 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -266,7 +266,7 @@ class Member < ActiveRecord::Base end def follow_id(member) - self.follows.where(:followed_id => @member.id).first if already_following?(member) + self.follows.where(:followed_id => member.id).first if already_following?(member) end end diff --git a/app/views/members/show.html.haml b/app/views/members/show.html.haml index bba4afab3..63f4aa27e 100644 --- a/app/views/members/show.html.haml +++ b/app/views/members/show.html.haml @@ -10,7 +10,7 @@ - if current_member != @member && !current_member.already_following?(@member) = link_to 'Follow', follows_path(:followed_id => @member.id), :method => :post, :class => 'btn btn-default' - if current_member.already_following?(@member) - - follow = current_member.follows.where(:followed_id => @member.id).first + - follow = current_member.follow_id(@member) = link_to 'Unfollow', follow_path(follow), :method => :delete, :class => 'btn btn-default' - content_for :member_rss_login_name, @member.login_name - content_for :member_rss_slug, @member.slug From b5e1b6bc22e377c4c4d3c6256b50bf6e8aa248bb Mon Sep 17 00:00:00 2001 From: Yoong Kang Lim Date: Thu, 13 Nov 2014 00:46:34 +1100 Subject: [PATCH 12/38] Delete unused views, add feature tests --- app/controllers/members_controller.rb | 10 ++++++++ app/models/ability.rb | 2 ++ app/models/follow.rb | 15 ++++++++++-- app/models/member.rb | 2 +- app/views/follows/_form.html.haml | 16 ------------- app/views/follows/edit.html.haml | 7 ------ app/views/follows/index.html.haml | 21 ----------------- app/views/follows/new.html.haml | 5 ---- app/views/follows/show.html.haml | 12 ---------- app/views/members/_account.html.haml | 6 +++++ app/views/members/show.html.haml | 6 ++--- app/views/members/view_followers.html.haml | 11 +++++++++ app/views/members/view_follows.html.haml | 10 ++++++++ config/routes.rb | 11 +++++---- spec/features/member_profile_spec.rb | 27 ++++++++++++++++++++++ spec/models/follow_spec.rb | 5 ---- spec/requests/follows_spec.rb | 11 --------- spec/routing/follows_routing_spec.rb | 20 ---------------- 18 files changed, 90 insertions(+), 107 deletions(-) delete mode 100644 app/views/follows/_form.html.haml delete mode 100644 app/views/follows/edit.html.haml delete mode 100644 app/views/follows/index.html.haml delete mode 100644 app/views/follows/new.html.haml delete mode 100644 app/views/follows/show.html.haml create mode 100644 app/views/members/view_followers.html.haml create mode 100644 app/views/members/view_follows.html.haml delete mode 100644 spec/models/follow_spec.rb delete mode 100644 spec/requests/follows_spec.rb diff --git a/app/controllers/members_controller.rb b/app/controllers/members_controller.rb index 08c04a359..dbdaaf9ef 100644 --- a/app/controllers/members_controller.rb +++ b/app/controllers/members_controller.rb @@ -34,4 +34,14 @@ class MembersController < ApplicationController end end + def view_follows + @member = Member.confirmed.find(params[:login_name]) + @follows = @member.followed + end + + def view_followers + @member = Member.confirmed.find(params[:login_name]) + @followers = @member.followers + end + end diff --git a/app/models/ability.rb b/app/models/ability.rb index 3e76c6738..92bfce14e 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -6,6 +6,8 @@ class Ability # everyone can do these things, even non-logged in can :read, :all + can :view_follows, Member + can :view_followers, Member # except these, which don't make sense if you're not logged in cannot :read, Notification diff --git a/app/models/follow.rb b/app/models/follow.rb index f57f1e76e..42624bd4f 100644 --- a/app/models/follow.rb +++ b/app/models/follow.rb @@ -1,6 +1,17 @@ class Follow < ActiveRecord::Base attr_accessible :followed_id, :member_id - belongs_to :member - belongs_to :followed, class_name: "Member" + belongs_to :member, :dependent => :destroy + belongs_to :followed, class_name: "Member", :dependent => :destroy validates :member_id, uniqueness: { :scope => :followed_id } + + after_create do + Notification.create( + :recipient_id => self.followed_id, + :sender_id => self.member_id, + :subject => "#{self.member.login_name} has followed you", + :body => "#{self.member.login_name} has followed you" + ) + end + + end diff --git a/app/models/member.rb b/app/models/member.rb index a72dd15a6..22749491b 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -265,7 +265,7 @@ class Member < ActiveRecord::Base self.follows.exists?(:followed_id => member.id) end - def follow_id(member) + def get_follow_id(member) self.follows.where(:followed_id => member.id).first if already_following?(member) end diff --git a/app/views/follows/_form.html.haml b/app/views/follows/_form.html.haml deleted file mode 100644 index f11f553f6..000000000 --- a/app/views/follows/_form.html.haml +++ /dev/null @@ -1,16 +0,0 @@ -= form_for @follow do |f| - - if @follow.errors.any? - #error_explanation - %h2= "#{pluralize(@follow.errors.count, "error")} prohibited this follow from being saved:" - %ul - - @follow.errors.full_messages.each do |msg| - %li= msg - - .field - = f.label :member_id - = f.number_field :member_id - .field - = f.label :followed_id - = f.number_field :followed_id - .actions - = f.submit 'Save' diff --git a/app/views/follows/edit.html.haml b/app/views/follows/edit.html.haml deleted file mode 100644 index 9ed5e22d5..000000000 --- a/app/views/follows/edit.html.haml +++ /dev/null @@ -1,7 +0,0 @@ -%h1 Editing follow - -= render 'form' - -= link_to 'Show', @follow -\| -= link_to 'Back', follows_path diff --git a/app/views/follows/index.html.haml b/app/views/follows/index.html.haml deleted file mode 100644 index 75f9ab0e4..000000000 --- a/app/views/follows/index.html.haml +++ /dev/null @@ -1,21 +0,0 @@ -%h1 Listing follows - -%table - %tr - %th Member - %th Followed - %th - %th - %th - - - @follows.each do |follow| - %tr - %td= follow.member_id - %td= follow.followed_id - %td= link_to 'Show', follow - %td= link_to 'Edit', edit_follow_path(follow) - %td= link_to 'Destroy', follow, :method => :delete, :data => { :confirm => 'Are you sure?' } - -%br - -= link_to 'New Follow', new_follow_path diff --git a/app/views/follows/new.html.haml b/app/views/follows/new.html.haml deleted file mode 100644 index fce286b48..000000000 --- a/app/views/follows/new.html.haml +++ /dev/null @@ -1,5 +0,0 @@ -%h1 New follow - -= render 'form' - -= link_to 'Back', follows_path diff --git a/app/views/follows/show.html.haml b/app/views/follows/show.html.haml deleted file mode 100644 index ea673e551..000000000 --- a/app/views/follows/show.html.haml +++ /dev/null @@ -1,12 +0,0 @@ -%p#notice= notice - -%p - %b Member: - = @follow.member_id -%p - %b Followed: - = @follow.followed_id - -= link_to 'Edit', edit_follow_path(@follow) -\| -= link_to 'Back', follows_path diff --git a/app/views/members/_account.html.haml b/app/views/members/_account.html.haml index 37ff0c699..e44bae027 100644 --- a/app/views/members/_account.html.haml +++ b/app/views/members/_account.html.haml @@ -9,4 +9,10 @@ = member.account_type account +%p + %strong Following: + = link_to member.follows.count, member_follows_path(member) +%p + %strong Followed by: + = link_to member.followers.count, member_followers_path(member) diff --git a/app/views/members/show.html.haml b/app/views/members/show.html.haml index 63f4aa27e..71152ac52 100644 --- a/app/views/members/show.html.haml +++ b/app/views/members/show.html.haml @@ -7,10 +7,10 @@ = link_to "Upgrade account", shop_path, :class => 'btn btn-default' -if can? :create, Notification and current_member != @member =link_to 'Send message', new_notification_path(:recipient_id => @member.id), :class => 'btn btn-default' - - if current_member != @member && !current_member.already_following?(@member) + - if member_signed_in? && current_member != @member && !current_member.already_following?(@member) = link_to 'Follow', follows_path(:followed_id => @member.id), :method => :post, :class => 'btn btn-default' - - if current_member.already_following?(@member) - - follow = current_member.follow_id(@member) + - if member_signed_in? && current_member.already_following?(@member) + - follow = current_member.get_follow_id(@member) = link_to 'Unfollow', follow_path(follow), :method => :delete, :class => 'btn btn-default' - content_for :member_rss_login_name, @member.login_name - content_for :member_rss_slug, @member.slug diff --git a/app/views/members/view_followers.html.haml b/app/views/members/view_followers.html.haml new file mode 100644 index 000000000..e196a8130 --- /dev/null +++ b/app/views/members/view_followers.html.haml @@ -0,0 +1,11 @@ +- content_for :title, @member.login_name + +%p Followed by: + +.row + .col-md-12 + - @followers.each do |f| + .col-md-4.three-across + .thumbnail + = render :partial => "members/thumbnail", :locals => { :member => f } + \ No newline at end of file diff --git a/app/views/members/view_follows.html.haml b/app/views/members/view_follows.html.haml new file mode 100644 index 000000000..ee2248239 --- /dev/null +++ b/app/views/members/view_follows.html.haml @@ -0,0 +1,10 @@ +- content_for :title, @member.login_name + +%p Follows: + +.row + .col-md-12 + - @follows.each do |f| + .col-md-4.three-across + .thumbnail + = render :partial => "members/thumbnail", :locals => { :member => f } diff --git a/config/routes.rb b/config/routes.rb index a740857ce..1b9c30c05 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,12 +1,10 @@ Growstuff::Application.routes.draw do - resources :follows - resources :plant_parts devise_for :members, :controllers => { :registrations => "registrations", :passwords => "passwords" } - resources :members + resources :members resources :photos @@ -43,6 +41,11 @@ Growstuff::Application.routes.draw do resources :forums resources :notifications + resources :follows, :only => [:create, :destroy] + get '/members/:login_name/follows' => 'members#view_follows', :as => 'member_follows' + get '/members/:login_name/followers' => 'members#view_followers', :as => 'member_followers' + + get '/places' => 'places#index' get '/places/search' => 'places#search', :as => 'search_places' get '/places/:place' => 'places#show', :as => 'place' @@ -81,6 +84,6 @@ Growstuff::Application.routes.draw do match '/admin/newsletter' => 'admin#newsletter', :as => :admin_newsletter match '/admin/:action' => 'admin#:action' - + end diff --git a/spec/features/member_profile_spec.rb b/spec/features/member_profile_spec.rb index 809b052a8..1520b215e 100644 --- a/spec/features/member_profile_spec.rb +++ b/spec/features/member_profile_spec.rb @@ -143,6 +143,33 @@ feature "member profile" do scenario "has a private message button" do expect(page).to have_link "Send message", :href => new_notification_path(:recipient_id => other_member.id) end + + scenario "has a follow button" do + expect(page).to have_link "Follow", :href => follows_path(:followed_id => other_member.id) + end + + scenario "following and unfollowing" do + click_link 'Follow' + expect(page).to have_content "Followed #{other_member.login_name}" + expect(page).to have_link "Unfollow", :href => follow_path(member.get_follow_id(other_member)) + + visit member_follows_path(member) + expect(page).to have_content "#{other_member.login_name}" + + visit member_followers_path(other_member) + expect(page).to have_content "#{member.login_name}" + + visit member_path(other_member) + click_link 'Unfollow' + expect(page).to have_content "Unfollowed #{other_member.login_name}" + + visit member_follows_path(member) + expect(page).to_not have_content "#{other_member.login_name}" + + visit member_followers_path(other_member) + expect(page).to_not have_content "#{member.login_name}" + end + end end diff --git a/spec/models/follow_spec.rb b/spec/models/follow_spec.rb deleted file mode 100644 index 7a7eb0fa5..000000000 --- a/spec/models/follow_spec.rb +++ /dev/null @@ -1,5 +0,0 @@ -require 'spec_helper' - -describe Follow do - pending "add some examples to (or delete) #{__FILE__}" -end diff --git a/spec/requests/follows_spec.rb b/spec/requests/follows_spec.rb deleted file mode 100644 index 32a4c2e44..000000000 --- a/spec/requests/follows_spec.rb +++ /dev/null @@ -1,11 +0,0 @@ -require 'spec_helper' - -describe "Follows" do - describe "GET /follows" 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 follows_path - response.status.should be(200) - end - end -end diff --git a/spec/routing/follows_routing_spec.rb b/spec/routing/follows_routing_spec.rb index 82ddc7fda..d4259e024 100644 --- a/spec/routing/follows_routing_spec.rb +++ b/spec/routing/follows_routing_spec.rb @@ -3,30 +3,10 @@ require "spec_helper" describe FollowsController do describe "routing" do - it "routes to #index" do - get("/follows").should route_to("follows#index") - end - - it "routes to #new" do - get("/follows/new").should route_to("follows#new") - end - - it "routes to #show" do - get("/follows/1").should route_to("follows#show", :id => "1") - end - - it "routes to #edit" do - get("/follows/1/edit").should route_to("follows#edit", :id => "1") - end - it "routes to #create" do post("/follows").should route_to("follows#create") end - it "routes to #update" do - put("/follows/1").should route_to("follows#update", :id => "1") - end - it "routes to #destroy" do delete("/follows/1").should route_to("follows#destroy", :id => "1") end From e687bd43dc6bdd8c5052d95de01878673802416b Mon Sep 17 00:00:00 2001 From: Yoong Kang Lim Date: Thu, 13 Nov 2014 01:22:28 +1100 Subject: [PATCH 13/38] Added model tests for follows --- spec/factories/follows.rb | 2 +- spec/models/follow_spec.rb | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 spec/models/follow_spec.rb diff --git a/spec/factories/follows.rb b/spec/factories/follows.rb index 756111732..711402374 100644 --- a/spec/factories/follows.rb +++ b/spec/factories/follows.rb @@ -1,7 +1,7 @@ FactoryGirl.define do factory :follow do member_id 1 -followed_id 1 + followed_id 2 end end diff --git a/spec/models/follow_spec.rb b/spec/models/follow_spec.rb new file mode 100644 index 000000000..f9302c9d3 --- /dev/null +++ b/spec/models/follow_spec.rb @@ -0,0 +1,18 @@ +require 'spec_helper' + +describe Follow do + + context "basic" do + before(:each) do + @member1 = FactoryGirl.create(:member) + @member2 = FactoryGirl.create(:member) + end + + it "sends a notification when a follow is created" do + expect { + Follow.create(:member_id => @member1.id, :followed_id => @member2.id) + }.to change(Notification, :count).by(1) + end + end + +end \ No newline at end of file From 03fea2a78513d26ca543d4241b2b89bfb8e036f4 Mon Sep 17 00:00:00 2001 From: Yoong Kang Lim Date: Thu, 13 Nov 2014 01:52:43 +1100 Subject: [PATCH 14/38] Remove dependent detroy as this wipes out both users. Woops. --- app/models/follow.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/follow.rb b/app/models/follow.rb index 42624bd4f..e312efc90 100644 --- a/app/models/follow.rb +++ b/app/models/follow.rb @@ -1,7 +1,7 @@ class Follow < ActiveRecord::Base attr_accessible :followed_id, :member_id - belongs_to :member, :dependent => :destroy - belongs_to :followed, class_name: "Member", :dependent => :destroy + belongs_to :member + belongs_to :followed, class_name: "Member" validates :member_id, uniqueness: { :scope => :followed_id } after_create do From 77f40a3dc227cb5779daa53092590bd653b8adf0 Mon Sep 17 00:00:00 2001 From: Yoong Kang Lim Date: Thu, 13 Nov 2014 02:10:54 +1100 Subject: [PATCH 15/38] Fixed comment + code style --- app/controllers/follows_controller.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/controllers/follows_controller.rb b/app/controllers/follows_controller.rb index b9e07f738..d6e38c81f 100644 --- a/app/controllers/follows_controller.rb +++ b/app/controllers/follows_controller.rb @@ -13,14 +13,13 @@ class FollowsController < ApplicationController end end - # DELETE /follows/1 - # DELETE /follows/1.json def destroy @follow = current_member.follows.find(params[:id]) + unfollowed_name = @follow.followed.login_name @follow.destroy - flash[:notice] = "Unfollowed #{ @follow.followed.login_name }" + flash[:notice] = "Unfollowed #{ unfollowed_name }" redirect_to root_path end end From 0eb5ae58aa44f46f2af9e90efdc1657e91ec9650 Mon Sep 17 00:00:00 2001 From: Yoong Kang Lim Date: Thu, 20 Nov 2014 00:42:46 +1100 Subject: [PATCH 16/38] Renamed member_id column in Follow table to follower_id. Made necessary modifications to models and tests. --- app/models/follow.rb | 12 ++++++------ app/models/member.rb | 4 ++-- ...130555_change_follows_member_id_to_follower_id.rb | 5 +++++ db/schema.rb | 4 ++-- spec/factories/follows.rb | 2 +- spec/models/follow_spec.rb | 2 +- 6 files changed, 17 insertions(+), 12 deletions(-) create mode 100644 db/migrate/20141119130555_change_follows_member_id_to_follower_id.rb diff --git a/app/models/follow.rb b/app/models/follow.rb index e312efc90..b1b011c41 100644 --- a/app/models/follow.rb +++ b/app/models/follow.rb @@ -1,15 +1,15 @@ class Follow < ActiveRecord::Base - attr_accessible :followed_id, :member_id - belongs_to :member + attr_accessible :followed_id, :follower_id + belongs_to :follower, class_name: "Member" belongs_to :followed, class_name: "Member" - validates :member_id, uniqueness: { :scope => :followed_id } + validates :follower_id, uniqueness: { :scope => :followed_id } after_create do Notification.create( :recipient_id => self.followed_id, - :sender_id => self.member_id, - :subject => "#{self.member.login_name} has followed you", - :body => "#{self.member.login_name} has followed you" + :sender_id => self.follower_id, + :subject => "#{self.follower.login_name} has followed you", + :body => "#{self.follower.login_name} has followed you" ) end diff --git a/app/models/member.rb b/app/models/member.rb index 22749491b..c34c2f558 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -27,11 +27,11 @@ class Member < ActiveRecord::Base has_many :photos - has_many :follows + has_many :follows, :class_name => "Follow", :foreign_key => "follower_id" has_many :followed, :through => :follows has_many :inverse_follows, :class_name => "Follow", :foreign_key => "followed_id" - has_many :followers, :through => :inverse_follows, :source => :member + has_many :followers, :through => :inverse_follows, :source => :follower default_scope order("lower(login_name) asc") scope :confirmed, where('confirmed_at IS NOT NULL') diff --git a/db/migrate/20141119130555_change_follows_member_id_to_follower_id.rb b/db/migrate/20141119130555_change_follows_member_id_to_follower_id.rb new file mode 100644 index 000000000..1ac6af7f2 --- /dev/null +++ b/db/migrate/20141119130555_change_follows_member_id_to_follower_id.rb @@ -0,0 +1,5 @@ +class ChangeFollowsMemberIdToFollowerId < ActiveRecord::Migration + def change + rename_column :follows, :member_id, :follower_id + end +end diff --git a/db/schema.rb b/db/schema.rb index e22a2289b..c3a45bf0c 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 => 20141111130849) do +ActiveRecord::Schema.define(:version => 20141119130555) do create_table "account_types", :force => true do |t| t.string "name", :null => false @@ -81,7 +81,7 @@ ActiveRecord::Schema.define(:version => 20141111130849) do add_index "crops_posts", ["crop_id"], :name => "index_crops_posts_on_crop_id" create_table "follows", :force => true do |t| - t.integer "member_id" + t.integer "follower_id" t.integer "followed_id" t.datetime "created_at", :null => false t.datetime "updated_at", :null => false diff --git a/spec/factories/follows.rb b/spec/factories/follows.rb index 711402374..d9bd13616 100644 --- a/spec/factories/follows.rb +++ b/spec/factories/follows.rb @@ -1,6 +1,6 @@ FactoryGirl.define do factory :follow do - member_id 1 + follower_id 1 followed_id 2 end diff --git a/spec/models/follow_spec.rb b/spec/models/follow_spec.rb index f9302c9d3..c1beb68c5 100644 --- a/spec/models/follow_spec.rb +++ b/spec/models/follow_spec.rb @@ -10,7 +10,7 @@ describe Follow do it "sends a notification when a follow is created" do expect { - Follow.create(:member_id => @member1.id, :followed_id => @member2.id) + Follow.create(:follower_id => @member1.id, :followed_id => @member2.id) }.to change(Notification, :count).by(1) end end From 996043d8fbca7b9dd46e61bd75633cc1a77b9c3d Mon Sep 17 00:00:00 2001 From: Yoong Kang Lim Date: Thu, 20 Nov 2014 01:04:35 +1100 Subject: [PATCH 17/38] Renamed get_follow_id to get_follow as it does not return id. Also added unit tests for the new methods in the member model. --- app/models/member.rb | 2 +- app/views/members/show.html.haml | 2 +- spec/features/member_profile_spec.rb | 2 +- spec/models/member_spec.rb | 26 ++++++++++++++++++++++++++ 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/app/models/member.rb b/app/models/member.rb index c34c2f558..63682bcdf 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -265,7 +265,7 @@ class Member < ActiveRecord::Base self.follows.exists?(:followed_id => member.id) end - def get_follow_id(member) + def get_follow(member) self.follows.where(:followed_id => member.id).first if already_following?(member) end diff --git a/app/views/members/show.html.haml b/app/views/members/show.html.haml index 71152ac52..e7c0bc93d 100644 --- a/app/views/members/show.html.haml +++ b/app/views/members/show.html.haml @@ -10,7 +10,7 @@ - if member_signed_in? && current_member != @member && !current_member.already_following?(@member) = link_to 'Follow', follows_path(:followed_id => @member.id), :method => :post, :class => 'btn btn-default' - if member_signed_in? && current_member.already_following?(@member) - - follow = current_member.get_follow_id(@member) + - follow = current_member.get_follow(@member) = link_to 'Unfollow', follow_path(follow), :method => :delete, :class => 'btn btn-default' - content_for :member_rss_login_name, @member.login_name - content_for :member_rss_slug, @member.slug diff --git a/spec/features/member_profile_spec.rb b/spec/features/member_profile_spec.rb index 1520b215e..b2efe71d3 100644 --- a/spec/features/member_profile_spec.rb +++ b/spec/features/member_profile_spec.rb @@ -151,7 +151,7 @@ feature "member profile" do scenario "following and unfollowing" do click_link 'Follow' expect(page).to have_content "Followed #{other_member.login_name}" - expect(page).to have_link "Unfollow", :href => follow_path(member.get_follow_id(other_member)) + expect(page).to have_link "Unfollow", :href => follow_path(member.get_follow(other_member)) visit member_follows_path(member) expect(page).to have_content "#{other_member.login_name}" diff --git a/spec/models/member_spec.rb b/spec/models/member_spec.rb index 49b66ef71..dbffaf941 100644 --- a/spec/models/member_spec.rb +++ b/spec/models/member_spec.rb @@ -381,4 +381,30 @@ describe 'member' do end end + context 'member who followed another member' do + before(:each) do + @member1 = FactoryGirl.create(:member) + @member2 = FactoryGirl.create(:member) + @member3 = FactoryGirl.create(:member) + @follow = @member1.follows.create(:follower_id => @member1.id, :followed_id => @member2.id) + end + + it 'detects that member is already following a member' do + expect(@member1.already_following?(@member2)).to eq true + end + + it 'detects that member is not already following a member' do + expect(@member1.already_following?(@member3)).to eq false + end + + it 'gets the correct follow for a followed member' do + expect(@member1.get_follow(@member2).id).to eq @follow.id + end + + it 'returns nil for a member that is not followed' do + expect(@member1.get_follow(@member3).nil?).to eq true + end + + end + end From 0ba6562d797ab1b8c299cb405e56c1517432be91 Mon Sep 17 00:00:00 2001 From: Yoong Kang Lim Date: Thu, 20 Nov 2014 01:46:04 +1100 Subject: [PATCH 18/38] Added more model tests for following behaviour --- spec/models/follow_spec.rb | 45 ++++++++++++++++++++++++++++++-------- spec/models/member_spec.rb | 2 +- 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/spec/models/follow_spec.rb b/spec/models/follow_spec.rb index c1beb68c5..4cba917be 100644 --- a/spec/models/follow_spec.rb +++ b/spec/models/follow_spec.rb @@ -2,16 +2,43 @@ require 'spec_helper' describe Follow do - context "basic" do - before(:each) do - @member1 = FactoryGirl.create(:member) - @member2 = FactoryGirl.create(:member) - end + before(:each) do + @member1 = FactoryGirl.create(:member) + @member2 = FactoryGirl.create(:member) + end - it "sends a notification when a follow is created" do - expect { - Follow.create(:follower_id => @member1.id, :followed_id => @member2.id) - }.to change(Notification, :count).by(1) + it "sends a notification when a follow is created" do + expect { + Follow.create(:follower_id => @member1.id, :followed_id => @member2.id) + }.to change(Notification, :count).by(1) + end + + it "does not delete any members when follow is deleted" do + expect { + follow = Follow.create(:follower_id => @member1.id, :followed_id => @member2.id) + follow.destroy + }.not_to change(Member, :count) + end + + context "when follow is created" do + + before (:each) do + @follow = Follow.create(:follower_id => @member1.id, :followed_id => @member2.id) + end + + it "should not duplicate follows" do + expect(Follow.create(:follower_id => @member1.id, :followed_id => @member2.id)).not_to be_valid + end + + it "should list users in following/follower collections when follow is created" do + expect(@member1.followed).to include(@member2) + expect(@member2.followers).to include(@member1) + end + + it "should no longer list users in following/follower collections when follow is deleted" do + @follow.destroy + expect(@member1.followed).not_to include(@member2) + expect(@member2.followers).not_to include(@member1) end end diff --git a/spec/models/member_spec.rb b/spec/models/member_spec.rb index dbffaf941..5594c9dbd 100644 --- a/spec/models/member_spec.rb +++ b/spec/models/member_spec.rb @@ -402,7 +402,7 @@ describe 'member' do end it 'returns nil for a member that is not followed' do - expect(@member1.get_follow(@member3).nil?).to eq true + expect(@member1.get_follow(@member3)).to be_nil end end From aeb7192f487025c664a5925be1033feb64a60e4c Mon Sep 17 00:00:00 2001 From: Yoong Kang Lim Date: Thu, 20 Nov 2014 23:46:15 +1100 Subject: [PATCH 19/38] Break up tests into different scenarios. Defined cancan ability for follows and updated member profile view --- app/models/ability.rb | 5 ++++ app/views/members/show.html.haml | 11 +++++---- spec/features/member_profile_spec.rb | 36 ++++++++++++++++++++++------ 3 files changed, 40 insertions(+), 12 deletions(-) diff --git a/app/models/ability.rb b/app/models/ability.rb index 92bfce14e..579a87022 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -93,6 +93,11 @@ class Ability cannot :update, OrderItem, :order => { :member_id => member.id, :completed_at => nil } cannot :destroy, OrderItem, :order => { :member_id => member.id, :completed_at => nil } + # following/unfollowing permissions + can :create, Follow do |f| + !member.already_following?(f.followed) && f.followed_id != member.id + end + if member.has_role? :admin can :read, :all diff --git a/app/views/members/show.html.haml b/app/views/members/show.html.haml index e7c0bc93d..5ff19b2eb 100644 --- a/app/views/members/show.html.haml +++ b/app/views/members/show.html.haml @@ -7,11 +7,12 @@ = link_to "Upgrade account", shop_path, :class => 'btn btn-default' -if can? :create, Notification and current_member != @member =link_to 'Send message', new_notification_path(:recipient_id => @member.id), :class => 'btn btn-default' - - if member_signed_in? && current_member != @member && !current_member.already_following?(@member) - = link_to 'Follow', follows_path(:followed_id => @member.id), :method => :post, :class => 'btn btn-default' - - if member_signed_in? && current_member.already_following?(@member) - - follow = current_member.get_follow(@member) - = link_to 'Unfollow', follow_path(follow), :method => :delete, :class => 'btn btn-default' + - if can? :create, Follow and current_member != @member + - if !current_member.already_following?(@member) + = link_to 'Follow', follows_path(:followed_id => @member.id), :method => :post, :class => 'btn btn-default' + - else + - follow = current_member.get_follow(@member) + = link_to 'Unfollow', follow_path(follow), :method => :delete, :class => 'btn btn-default' - content_for :member_rss_login_name, @member.login_name - content_for :member_rss_slug, @member.slug diff --git a/spec/features/member_profile_spec.rb b/spec/features/member_profile_spec.rb index b2efe71d3..626f00657 100644 --- a/spec/features/member_profile_spec.rb +++ b/spec/features/member_profile_spec.rb @@ -13,6 +13,8 @@ feature "member profile" do expect(page).to have_content "Account type: Free account" expect(page).to have_content "#{member.login_name}'s gardens" expect(page).to have_link "More about this garden...", :href => garden_path(member.gardens.first) + expect(page).to_not have_link "Follow" + expect(page).to_not have_link "Unfollow" end scenario "no bio" do @@ -147,27 +149,47 @@ feature "member profile" do scenario "has a follow button" do expect(page).to have_link "Follow", :href => follows_path(:followed_id => other_member.id) end + end - scenario "following and unfollowing" do + context "following another member" do + background do + visit member_path(other_member) click_link 'Follow' + end + + scenario "has correct message and unfollow button" do expect(page).to have_content "Followed #{other_member.login_name}" expect(page).to have_link "Unfollow", :href => follow_path(member.get_follow(other_member)) + end + scenario "has a followed member listed in the following page" do visit member_follows_path(member) expect(page).to have_content "#{other_member.login_name}" + end - visit member_followers_path(other_member) - expect(page).to have_content "#{member.login_name}" - - visit member_path(other_member) + scenario "has correct message and follow button after unfollow" do click_link 'Unfollow' expect(page).to have_content "Unfollowed #{other_member.login_name}" + visit member_path(other_member) # unfollowing redirects to root + expect(page).to have_link "Follow", :href => follows_path(:followed_id => other_member.id) + end + scenario "has member in following list" do visit member_follows_path(member) - expect(page).to_not have_content "#{other_member.login_name}" + expect(page).to have_content "#{other_member.login_name}" + end + scenario "appears in in followed member's followers list" do visit member_followers_path(other_member) - expect(page).to_not have_content "#{member.login_name}" + expect(page).to have_content "#{member.login_name}" + end + + scenario "removes members from following and followers lists after unfollow" do + click_link 'Unfollow' + visit member_follows_path(member) + expect(page).not_to have_content "#{other_member.login_name}" + visit member_followers_path(other_member) + expect(page).not_to have_content "#{member.login_name}" end end From 5de6759917329bd90eb5ebfa0004b73d9f5f581c Mon Sep 17 00:00:00 2001 From: Yoong Kang Lim Date: Fri, 21 Nov 2014 00:29:45 +1100 Subject: [PATCH 20/38] Moved number of follows/followers under activity and added pagination. --- app/controllers/members_controller.rb | 4 ++-- app/views/members/_account.html.haml | 7 ------- app/views/members/_stats.html.haml | 13 +++++++++++++ app/views/members/view_followers.html.haml | 11 ++++++++--- app/views/members/view_follows.html.haml | 10 ++++++++-- 5 files changed, 31 insertions(+), 14 deletions(-) diff --git a/app/controllers/members_controller.rb b/app/controllers/members_controller.rb index dbdaaf9ef..ac53f4194 100644 --- a/app/controllers/members_controller.rb +++ b/app/controllers/members_controller.rb @@ -36,12 +36,12 @@ class MembersController < ApplicationController def view_follows @member = Member.confirmed.find(params[:login_name]) - @follows = @member.followed + @follows = @member.followed.paginate(:page => params[:page]) end def view_followers @member = Member.confirmed.find(params[:login_name]) - @followers = @member.followers + @followers = @member.followers.paginate(:page => params[:page]) end end diff --git a/app/views/members/_account.html.haml b/app/views/members/_account.html.haml index e44bae027..68dfbd591 100644 --- a/app/views/members/_account.html.haml +++ b/app/views/members/_account.html.haml @@ -9,10 +9,3 @@ = member.account_type account -%p - %strong Following: - = link_to member.follows.count, member_follows_path(member) - -%p - %strong Followed by: - = link_to member.followers.count, member_followers_path(member) diff --git a/app/views/members/_stats.html.haml b/app/views/members/_stats.html.haml index 38d6b96c3..0929e5998 100644 --- a/app/views/members/_stats.html.haml +++ b/app/views/members/_stats.html.haml @@ -21,3 +21,16 @@ = link_to pluralize(member.posts.count, "post"), posts_by_author_path(:author => member) - else 0 posts + + %li + - if member.followed.count > 0 + = link_to pluralize(member.followed.count, "follow"), member_follows_path(member) + - else + 0 following + + %li + - if member.followers.count > 0 + = link_to pluralize(member.followers.count, "follower"), member_followers_path(member) + - else + 0 followers + diff --git a/app/views/members/view_followers.html.haml b/app/views/members/view_followers.html.haml index e196a8130..25a10a860 100644 --- a/app/views/members/view_followers.html.haml +++ b/app/views/members/view_followers.html.haml @@ -1,6 +1,8 @@ -- content_for :title, @member.login_name +- content_for :title, "#{@member.login_name}'s followers" -%p Followed by: +%div.pagination + = page_entries_info @followers, :model => "members" + = will_paginate @followers .row .col-md-12 @@ -8,4 +10,7 @@ .col-md-4.three-across .thumbnail = render :partial => "members/thumbnail", :locals => { :member => f } - \ No newline at end of file + +%div.pagination + = page_entries_info @followers, :model => "members" + = will_paginate @followers \ No newline at end of file diff --git a/app/views/members/view_follows.html.haml b/app/views/members/view_follows.html.haml index ee2248239..93d2695ac 100644 --- a/app/views/members/view_follows.html.haml +++ b/app/views/members/view_follows.html.haml @@ -1,6 +1,8 @@ -- content_for :title, @member.login_name +- content_for :title, "#{@member.login_name}'s follows" -%p Follows: +%div.pagination + = page_entries_info @follows, :model => "members" + = will_paginate @follows .row .col-md-12 @@ -8,3 +10,7 @@ .col-md-4.three-across .thumbnail = render :partial => "members/thumbnail", :locals => { :member => f } + +%div.pagination + = page_entries_info @follows, :model => "members" + = will_paginate @follows \ No newline at end of file From 2ca42bbae38f50f3b3cda0c7bb8fcca6462c3b0f Mon Sep 17 00:00:00 2001 From: Yoong Kang Lim Date: Fri, 21 Nov 2014 01:05:23 +1100 Subject: [PATCH 21/38] Slight modification to the notification wording. --- app/models/follow.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/follow.rb b/app/models/follow.rb index b1b011c41..55b2ce95c 100644 --- a/app/models/follow.rb +++ b/app/models/follow.rb @@ -8,8 +8,8 @@ class Follow < ActiveRecord::Base Notification.create( :recipient_id => self.followed_id, :sender_id => self.follower_id, - :subject => "#{self.follower.login_name} has followed you", - :body => "#{self.follower.login_name} has followed you" + :subject => "#{self.follower.login_name} is now following you", + :body => "#{self.follower.login_name} just followed you on Growstuff. " ) end From 8c55a6101d27ed76838b165c3ca77740564a6f83 Mon Sep 17 00:00:00 2001 From: Yoong Kang Lim Date: Fri, 21 Nov 2014 01:14:12 +1100 Subject: [PATCH 22/38] Formatting problem --- spec/models/follow_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/models/follow_spec.rb b/spec/models/follow_spec.rb index 4cba917be..3b672af34 100644 --- a/spec/models/follow_spec.rb +++ b/spec/models/follow_spec.rb @@ -7,7 +7,7 @@ describe Follow do @member2 = FactoryGirl.create(:member) end - it "sends a notification when a follow is created" do + it "sends a notification when a follow is created" do expect { Follow.create(:follower_id => @member1.id, :followed_id => @member2.id) }.to change(Notification, :count).by(1) From 4e19da56a0f204a45a344d3fb8fa764fcf1e79e4 Mon Sep 17 00:00:00 2001 From: Skud Date: Sun, 30 Nov 2014 14:51:33 +1100 Subject: [PATCH 23/38] Rearrange fields in crop uploads (sci names last) --- app/models/crop.rb | 4 +- db/schema.rb | 1 + db/seeds/crops-00.csv | 466 ++++++++++++++++----------------- db/seeds/crops-10-peppers.csv | 122 ++++----- db/seeds/crops-11-tomatoes.csv | 82 +++--- spec/models/crop_spec.rb | 9 +- 6 files changed, 342 insertions(+), 342 deletions(-) diff --git a/app/models/crop.rb b/app/models/crop.rb index 9777d8fd4..5f4758366 100644 --- a/app/models/crop.rb +++ b/app/models/crop.rb @@ -122,12 +122,12 @@ class Crop < ActiveRecord::Base # used by db/seeds.rb and rake growstuff:import_crops # CSV fields: # - name (required) -# - scientific name (optional, can be picked up from parent if it has one) # - en_wikipedia_url (required) # - parent (name, optional) +# - scientific name (optional, can be picked up from parent if it has one) def Crop.create_from_csv(row) - name,scientific_name,en_wikipedia_url,parent = row + name,en_wikipedia_url,parent,scientific_name = row cropbot = Member.find_by_login_name('cropbot') raise "cropbot account not found: run rake db:seed" unless cropbot diff --git a/db/schema.rb b/db/schema.rb index 39a68cab2..72fcb7231 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -262,6 +262,7 @@ ActiveRecord::Schema.define(:version => 20141018111015) do t.datetime "updated_at", :null => false t.string "slug" t.integer "forum_id" + t.integer "parent_id" end add_index "posts", ["created_at", "author_id"], :name => "index_updates_on_created_at_and_user_id" diff --git a/db/seeds/crops-00.csv b/db/seeds/crops-00.csv index ab0d135fa..adad852cb 100644 --- a/db/seeds/crops-00.csv +++ b/db/seeds/crops-00.csv @@ -1,233 +1,233 @@ -achiote,Bixa orellana,https://en.wikipedia.org/wiki/Bixa_orellana -ackee,Blighia sapida,https://en.wikipedia.org/wiki/Ackee -acuyo,Piper auritum,https://en.wikipedia.org/wiki/Piper_auritum -alexanders,Smyrnium olusatrum,https://en.wikipedia.org/wiki/Alexanders -alfalfa,Medicago sativa,https://en.wikipedia.org/wiki/Alfalfa -allspice,Pimenta dioica,https://en.wikipedia.org/wiki/Allspice -almond,Prunus dulcis,https://en.wikipedia.org/wiki/Almond -amaranth,Amaranthus spp.,https://en.wikipedia.org/wiki/Amaranth -anise,Pimpinella anisum,https://en.wikipedia.org/wiki/Anise -apple,Malus domestica,https://en.wikipedia.org/wiki/Apple -apple mint,Mentha suaveolens,https://en.wikipedia.org/wiki/Apple_mint -apricot,Prunus armeniaca,https://en.wikipedia.org/wiki/Apricot -arrowroot,Maranta arundinacea,https://en.wikipedia.org/wiki/Maranta_arundinacea -artichoke,Cynara cardunculus,https://en.wikipedia.org/wiki/Artichoke -arugula,Eruca sativa,https://en.wikipedia.org/wiki/Arugula -asparagus,Asparagus officinalis,https://en.wikipedia.org/wiki/Asparagus -avocado,Persea americana,https://en.wikipedia.org/wiki/Avocado -banana,Musa spp.,https://en.wikipedia.org/wiki/Banana -barley,Hordeum vulgare,https://en.wikipedia.org/wiki/Barley -basil,Ocimum basilicum,https://en.wikipedia.org/wiki/Basil -bay,Laurus nobilis,https://en.wikipedia.org/wiki/Bay_Laurel -bean,Phaseolus vulgaris,https://en.wikipedia.org/wiki/Common_bean -beet,Beta vulgaris,https://en.wikipedia.org/wiki/Beet -bell pepper,Capsicum annuum,https://en.wikipedia.org/wiki/Bell_pepper -bitter melon,Momordica charantia,https://en.wikipedia.org/wiki/Bitter_melon -blackberry,Rubus fruticosus,https://en.wikipedia.org/wiki/Blackberry -blackcurrant,Ribes spp.,https://en.wikipedia.org/wiki/Ribes -borage,Borago officinalis,https://en.wikipedia.org/wiki/Borage -breadfruit,Artocarpus altilis,https://en.wikipedia.org/wiki/Breadfruit -broccoli,Brassica oleracea,https://en.wikipedia.org/wiki/Broccoli -Brussels sprout,Brassica oleracea,https://en.wikipedia.org/wiki/Brussels_sprout -buckwheat,Fagopyrum esculentum,https://en.wikipedia.org/wiki/Buckwheat -cabbage,Brassica oleracea,https://en.wikipedia.org/wiki/Cabbage -cape gooseberry,Physalis peruviana,https://en.wikipedia.org/wiki/Physalis_peruviana -caper,Capparis spinosa,https://en.wikipedia.org/wiki/Caper -cardoon,Cynara cardunculus,https://en.wikipedia.org/wiki/Cardoon -carrot,Daucus carota,https://en.wikipedia.org/wiki/Carrot -cassava,Manihot esculenta,https://en.wikipedia.org/wiki/Cassava -catnip,Nepeta cataria,https://en.wikipedia.org/wiki/Nepeta_cataria -cauliflower,Brassica oleracea,https://en.wikipedia.org/wiki/Cauliflower -cayenne pepper,Capsicum annuum,https://en.wikipedia.org/wiki/Cayenne_pepper -celeriac,Apium graveolens var. rapaceum,https://en.wikipedia.org/wiki/Celeriac -celery,Apium graveolens,https://en.wikipedia.org/wiki/Celery -chamomile,Matricaria chamomila,https://en.wikipedia.org/wiki/Matricaria_recutita -chaya,Cnidoscolus aconitifolius,https://en.wikipedia.org/wiki/Cnidoscolus_aconitifolius -chayote,Sechium edule,https://en.wikipedia.org/wiki/Chayote -cherry,Prunus avium,https://en.wikipedia.org/wiki/Cherry -chervil,Anthriscus cerefolium,https://en.wikipedia.org/wiki/Chervil -chestnut,Castanea spp.,https://en.wikipedia.org/wiki/Chestnut -chickpeas,Cicer arietinum,https://en.wikipedia.org/wiki/Chickpea -chickweed,Stellaria,https://en.wikipedia.org/wiki/Stellaria -chicory,Cichorium intybus,https://en.wikipedia.org/wiki/Chicory -chinese cabbage,Brassica rapa (pekinensis),https://en.wikipedia.org/wiki/Chinese_cabbage -chives,Allium schoenoprasum,https://en.wikipedia.org/wiki/Chives -cicely,Myrrhis odorata,https://en.wikipedia.org/wiki/Cicely -citron,Citrus medica,https://en.wikipedia.org/wiki/Citron -coconut,Cocos nucifera,https://en.wikipedia.org/wiki/Coconut -collard greens,Brassica oleracea (acephala),https://en.wikipedia.org/wiki/Collard_greens -comfrey,Symphytum officinale,https://en.wikipedia.org/wiki/Comfrey -coriander,Coriandrum sativum,https://en.wikipedia.org/wiki/Coriander -corn,Zea mays,https://en.wikipedia.org/wiki/Corn -corn salad,Valerianella locusta,https://en.wikipedia.org/wiki/Corn_salad -cress,Lepidium sativum,https://en.wikipedia.org/wiki/Garden_cress -cucumber,Cucumis sativus,https://en.wikipedia.org/wiki/Cucumbers -cumin,Cuminum cyminum,https://en.wikipedia.org/wiki/Cumin -cumquat,Citrus japonica,https://en.wikipedia.org/wiki/Kumquat -curry leaf,Murraya koenigii,https://en.wikipedia.org/wiki/Curry-leaf_Tree -curry plant,Helichrysum italicum,https://en.wikipedia.org/wiki/Helichrysum_italicum -daikon,Raphanus sativus Longipinnatus group,https://en.wikipedia.org/wiki/Daikon -dandelion,Taraxacum officinale,https://en.wikipedia.org/wiki/Dandelion -dates,Phoenix dactylifera,https://en.wikipedia.org/wiki/Date_%28fruit%29 -desert lime,Citrus glauca,https://en.wikipedia.org/wiki/Citrus_glauca -dill,Anethum graveolens,https://en.wikipedia.org/wiki/Dill -dog rose,Rosa canina,https://en.wikipedia.org/wiki/Rosa_canina -durian,Durio,https://en.wikipedia.org/wiki/Durian -eggplant,Solanum melongena,https://en.wikipedia.org/wiki/Eggplant -elderberry,Sambucus nigra,https://en.wikipedia.org/wiki/Sambucus_nigra -endive,Cichorium endivia,https://en.wikipedia.org/wiki/Endive -epazote,Dysphania ambrosioides,https://en.wikipedia.org/wiki/Epazote -fava bean,Vicia faba,https://en.wikipedia.org/wiki/Vicia_faba -feijoa,Acca sellowiana,https://en.wikipedia.org/wiki/Acca_sellowiana -fennel,Foeniculum vulgare,https://en.wikipedia.org/wiki/Fennel -fenugreek,Trigonella foenum-graecum,https://en.wikipedia.org/wiki/Fenugreek -fiddlehead,Pteridium aquilinum,https://en.wikipedia.org/wiki/Fiddlehead -fig,Ficus carica,https://en.wikipedia.org/wiki/Common_fig -flax,Linum usitatissimum,https://en.wikipedia.org/wiki/Flax -garlic,Allium sativum,https://en.wikipedia.org/wiki/Garlic -garlic chives,Allium tuberosum,https://en.wikipedia.org/wiki/Garlic_chives -ginger,Zingiber officinale,https://en.wikipedia.org/wiki/Ginger -gooseberry,Ribes uva-crispa,https://en.wikipedia.org/wiki/Gooseberry -grapefruit,Citrus paradisi,https://en.wikipedia.org/wiki/Grapefruit -grapes,Vitis spp.,https://en.wikipedia.org/wiki/Grape -guava,Psidium spp.,https://en.wikipedia.org/wiki/Guava -habanero,Capsicum chinense,https://en.wikipedia.org/wiki/Habanero -hibiscus,Hibiscus,https://en.wikipedia.org/wiki/Hibiscus -horseradish,Armoracia rusticana,https://en.wikipedia.org/wiki/Horseradish -jasmine,Jasminum officinale,https://en.wikipedia.org/wiki/Jasmine -Jerusalem artichoke,Helianthus tuberosus,https://en.wikipedia.org/wiki/Jerusalem_artichoke -jicama,Pachyrhizus erosus,https://en.wikipedia.org/wiki/Jicama -juniper berry,Juniperus communis,https://en.wikipedia.org/wiki/Juniper_berry -kaffir lime,Citrus x hystrix,https://en.wikipedia.org/wiki/Kaffir_lime -kale,Brassica oleracea (acephala),https://en.wikipedia.org/wiki/Kale -kava,Piper methysticum,https://en.wikipedia.org/wiki/Kava -kohlrabi,Brassica oleracea (gongylodes),https://en.wikipedia.org/wiki/Kohlrabi -lavender,Lavandula spp.,https://en.wikipedia.org/wiki/Lavender -leek,Allium ampeloprasum var. porrum,https://en.wikipedia.org/wiki/Leeks -lemon,Citrus limon,https://en.wikipedia.org/wiki/Lemon -lemon balm,Melissa officinalis,https://en.wikipedia.org/wiki/Lemon_balm -lemon myrtle,Backhousia citriodora,https://en.wikipedia.org/wiki/Backhousia_citriodora -lemon verbena,Aloysia citrodora,https://en.wikipedia.org/wiki/Aloysia_citrodora -lemongrass,Cymbopogon spp.,https://en.wikipedia.org/wiki/Lemongrass -lentils,Lens culinaris,https://en.wikipedia.org/wiki/Lentil -lettuce,Lactuca sativa,https://en.wikipedia.org/wiki/Lettuce -licorice,Glycyrrhiza glabra,https://en.wikipedia.org/wiki/Licorice -lillipilli,Syzygium luehmannii,https://en.wikipedia.org/wiki/Syzygium_luehmannii -lima bean,Phaseolus lunatus,https://en.wikipedia.org/wiki/Phaseolus_lunatus -lime,Citrus spp.,https://en.wikipedia.org/wiki/Lime_%28fruit%29 -lovage,Levisticum officinale,https://en.wikipedia.org/wiki/Lovage -luffa,Luffa cylindrica,https://en.wikipedia.org/wiki/Luffa -lupin bean,Lupinus luteus,https://en.wikipedia.org/wiki/Lupin_bean -macadamia,Macadamia,https://en.wikipedia.org/wiki/Macadamia -Malabar spinach,Basella alba,https://en.wikipedia.org/wiki/Basella_alba -mandarin,Citrus reticulata,https://en.wikipedia.org/wiki/Mandarin_orange -mango,Mangifera spp.,https://en.wikipedia.org/wiki/Mango -maracuja,Passiflora edulis,https://en.wikipedia.org/wiki/Maracuja -marjoram,Origanum majorana,https://en.wikipedia.org/wiki/Marjoram -marshmallow,Althaea officinalis,https://en.wikipedia.org/wiki/Althaea_officinalis -medlar,Mespilus germanica,https://en.wikipedia.org/wiki/Mespilus_germanica -melon,Cucumis melo,https://en.wikipedia.org/wiki/Melon -miner's lettuce,Claytonia perfoliata,https://en.wikipedia.org/wiki/Claytonia_perfoliata -mint,Mentha spicata,https://en.wikipedia.org/wiki/Mentha_spicata -mung bean,Vigna radiata,https://en.wikipedia.org/wiki/Mung_bean -mustard,Brassica juncea,https://en.wikipedia.org/wiki/Mustard_plant -nasturtium,Tropaeloum spp.,https://en.wikipedia.org/wiki/Tropaeolum -New Zealand spinach,Tetragonia tetragonioides,https://en.wikipedia.org/wiki/Tetragonia -nigella,Nigella sativa,https://en.wikipedia.org/wiki/Nigella_sativa -oats,Avena sativa,https://en.wikipedia.org/wiki/Oats -okra,Abelmoschus esculentus,https://en.wikipedia.org/wiki/Okra -olive,Olea europaea,https://en.wikipedia.org/wiki/Olive -onion,Allium cepa,https://en.wikipedia.org/wiki/Onions -orange,Citrus sinensis,https://en.wikipedia.org/wiki/Orange_%28fruit%29 -oregano,Origanum vulgare,https://en.wikipedia.org/wiki/Oregano -parsley,Petroselinum hortense,https://en.wikipedia.org/wiki/Parsley -parsnip,Pastinaca sativa,https://en.wikipedia.org/wiki/Parsnip -passion fruit,Passiflora edulis,https://en.wikipedia.org/wiki/Passionfruit -pea,Pisum sativum,https://en.wikipedia.org/wiki/Pea -peach,Prunus persica,https://en.wikipedia.org/wiki/Peach -peach,Prunus persica,https://en.wikipedia.org/wiki/Peach -peanut,Arachis hypogaea,https://en.wikipedia.org/wiki/Peanut -pear,Pyrus spp.,https://en.wikipedia.org/wiki/Pear -pearl millet,Pennisetum glaucum,https://en.wikipedia.org/wiki/Pearl_millet -pecan,Carya illinoinensis,https://en.wikipedia.org/wiki/Pecan -peppermint,Mentha x piperita,https://en.wikipedia.org/wiki/Peppermint -Persian lime,Citrus latifolia,https://en.wikipedia.org/wiki/Persian_lime -persimmon,Diospyros spp.,https://en.wikipedia.org/wiki/Persimmon -pigeon pea,Cajanus cajan,https://en.wikipedia.org/wiki/Pigeon_pea -pigface,Carpobrotus glaucescens,https://en.wikipedia.org/wiki/Carpobrotus_glaucescens -pineapple,Ananas comosus,https://en.wikipedia.org/wiki/Pineapple -pistachio,Pistacia vera,https://en.wikipedia.org/wiki/Pistachio -plantain,Musa spp.,https://en.wikipedia.org/wiki/Plantain -plum,Prunus spp.,https://en.wikipedia.org/wiki/Plum -pomegranate,Punica granatum,https://en.wikipedia.org/wiki/Pomegranate -pomelo,Citrus maxima,https://en.wikipedia.org/wiki/Pomelo -potato,Solanum tuberosum,https://en.wikipedia.org/wiki/Potatoes -prickly pear,Opuntia,https://en.wikipedia.org/wiki/Opuntia -pumpkin,Cucurbita spp.,https://en.wikipedia.org/wiki/Pumpkin -purslane,Portulaca oleracea,https://en.wikipedia.org/wiki/Portulaca_oleracea -quandong,Santalum acuminatum,https://en.wikipedia.org/wiki/Santalum_acuminatum -quince,Cydonia oblonga,https://en.wikipedia.org/wiki/Quince -quinoa,Chenopodium quinoa,https://en.wikipedia.org/wiki/Quinoa -radicchio,Cichorium intybus,https://en.wikipedia.org/wiki/Radicchio -radish,Raphanus sativus,https://en.wikipedia.org/wiki/Radish -rapeseed,Brassica napus,https://en.wikipedia.org/wiki/Rapeseed -raspberry,Rubus idaeus,https://en.wikipedia.org/wiki/Rubus_idaeus -rhubarb,Rheum rhabarbarum,https://en.wikipedia.org/wiki/Rhubarb -rice,Oryza sativa,https://en.wikipedia.org/wiki/Rice -rice bean,Vigna umbellata,https://en.wikipedia.org/wiki/Ricebean -rose,Rosa,https://en.wikipedia.org/wiki/Rose -roselle,Hibiscus sabdariffa,https://en.wikipedia.org/wiki/Roselle_%28plant%29 -rosemary,Rosmarinus officinalis,https://en.wikipedia.org/wiki/Rosemary -rue,Ruta graveolens,https://en.wikipedia.org/wiki/Common_Rue -runner bean,Phaseolus coccineus,https://en.wikipedia.org/wiki/Runner_bean -rutabaga,Brassica napus Napobrassica group,https://en.wikipedia.org/wiki/Rutabaga -rye,Secale cereale,https://en.wikipedia.org/wiki/Rye -safflower,Carthamus tinctorius,https://en.wikipedia.org/wiki/Safflower -saffron,Crocus sativus,https://en.wikipedia.org/wiki/Saffron -sage,Salvia officinalis,https://en.wikipedia.org/wiki/Salvia_officinalis -salad burnet,Sanguisorba minor,https://en.wikipedia.org/wiki/Salad_burnet -salsify,Tragopogon porrifolius,https://en.wikipedia.org/wiki/Salsify -samphire,Crithmum maritimum,https://en.wikipedia.org/wiki/Rock_samphire -sassafras,Sassafras albidum,https://en.wikipedia.org/wiki/Sassafras_albidum -sesame,Sesamum indicum,https://en.wikipedia.org/wiki/Sesame -shallot,Allium cepa var. aggregatum,https://en.wikipedia.org/wiki/Shallot -sorghum,Sorghum spp.,https://en.wikipedia.org/wiki/Sorghum -sorrel,Rumex acetosa,https://en.wikipedia.org/wiki/Sorrel -soursop,Annona muricata,https://en.wikipedia.org/wiki/Soursop -soybean,Glycine max,https://en.wikipedia.org/wiki/Soybean -spearmint,Mentha spicata,https://en.wikipedia.org/wiki/Mentha_spicata -spinach,Spinacia oleracea,https://en.wikipedia.org/wiki/Spinach -star anise,Illicium verum,https://en.wikipedia.org/wiki/Star_anise -starfruit,Averrhoa carambola,https://en.wikipedia.org/wiki/Starfruit -stevia,Stevia rebaudiana,https://en.wikipedia.org/wiki/Stevia -strawberry,Fragaria ananassa,https://en.wikipedia.org/wiki/Strawberry -summer savory,Satureja hortensis,https://en.wikipedia.org/wiki/Summer_savory -sunflowers,Helianthus annuus,https://en.wikipedia.org/wiki/Sunflower -sweet potato,Ipomoea batatas,https://en.wikipedia.org/wiki/Sweet_potato -Swiss chard,Beta vulgaris var. cicla,https://en.wikipedia.org/wiki/Swiss_chard -tamarillo,Solanum betaceum ,https://en.wikipedia.org/wiki/Tamarillo -tamarind,Tamarindus indica,https://en.wikipedia.org/wiki/Tamarind -tangerine,Citrus tangerina,https://en.wikipedia.org/wiki/Tangerine -tansy,Tanacetum vulgare,https://en.wikipedia.org/wiki/Tansy -taro,Colocasia esculenta,https://en.wikipedia.org/wiki/Taro -tarragon,Artemisia dracunculus,https://en.wikipedia.org/wiki/Tarragon -thyme,Thymus mongolicus,https://en.wikipedia.org/wiki/Thyme -tomatillo,Physalis philadelphica,https://en.wikipedia.org/wiki/Tomatillo -tomato,Solanum lycopersicum,https://en.wikipedia.org/wiki/Tomato -turmeric,Curcuma longa,https://en.wikipedia.org/wiki/Turmeric -turnip,Brassica rapa var. rapa,https://en.wikipedia.org/wiki/Turnip -urad bean,Vigna mungo,https://en.wikipedia.org/wiki/Urad_(bean) -valerian,Valeriana officinalis,https://en.wikipedia.org/wiki/Valerian_%28plant%29 -vanilla,Vanilla planifolia,https://en.wikipedia.org/wiki/Vanilla -walnut,Juglans spp.,https://en.wikipedia.org/wiki/Walnut -wasabi,Wasabia japonica,https://en.wikipedia.org/wiki/Wasabi -watermelon,Citrullus lanatus,https://en.wikipedia.org/wiki/Watermelon -wheat,Triticum spp.,https://en.wikipedia.org/wiki/Wheat -winter savory,Satureja montana,https://en.wikipedia.org/wiki/Winter_savory -wormwood,Artemisia absinthium,https://en.wikipedia.org/wiki/Artemisia_absinthium -yam,Dioscorea spp.,https://en.wikipedia.org/wiki/Yam_(vegetable) -yardlong bean,Vigna unguiculata (sesquipedalis),https://en.wikipedia.org/wiki/Yardlong_bean -yarrow,Achillea millefolium,https://en.wikipedia.org/wiki/Achillea_millefolium -zucchini,Cucurbita pepo.,https://en.wikipedia.org/wiki/Zucchini -coffee,Coffea,https://en.wikipedia.org/wiki/Coffee -tea,Camellia sinensis,https://en.wikipedia.org/wiki/Tea +achiote,https://en.wikipedia.org/wiki/Bixa_orellana,,Bixa orellana +ackee,https://en.wikipedia.org/wiki/Ackee,,Blighia sapida +acuyo,https://en.wikipedia.org/wiki/Piper_auritum,,Piper auritum +alexanders,https://en.wikipedia.org/wiki/Alexanders,,Smyrnium olusatrum +alfalfa,https://en.wikipedia.org/wiki/Alfalfa,,Medicago sativa +allspice,https://en.wikipedia.org/wiki/Allspice,,Pimenta dioica +almond,https://en.wikipedia.org/wiki/Almond,,Prunus dulcis +amaranth,https://en.wikipedia.org/wiki/Amaranth,,Amaranthus spp. +anise,https://en.wikipedia.org/wiki/Anise,,Pimpinella anisum +apple,https://en.wikipedia.org/wiki/Apple,,Malus domestica +apple mint,https://en.wikipedia.org/wiki/Apple_mint,,Mentha suaveolens +apricot,https://en.wikipedia.org/wiki/Apricot,,Prunus armeniaca +arrowroot,https://en.wikipedia.org/wiki/Maranta_arundinacea,,Maranta arundinacea +artichoke,https://en.wikipedia.org/wiki/Artichoke,,Cynara cardunculus +arugula,https://en.wikipedia.org/wiki/Arugula,,Eruca sativa +asparagus,https://en.wikipedia.org/wiki/Asparagus,,Asparagus officinalis +avocado,https://en.wikipedia.org/wiki/Avocado,,Persea americana +banana,https://en.wikipedia.org/wiki/Banana,,Musa spp. +barley,https://en.wikipedia.org/wiki/Barley,,Hordeum vulgare +basil,https://en.wikipedia.org/wiki/Basil,,Ocimum basilicum +bay,https://en.wikipedia.org/wiki/Bay_Laurel,,Laurus nobilis +bean,https://en.wikipedia.org/wiki/Common_bean,,Phaseolus vulgaris +beet,https://en.wikipedia.org/wiki/Beet,,Beta vulgaris +bell pepper,https://en.wikipedia.org/wiki/Bell_pepper,,Capsicum annuum +bitter melon,https://en.wikipedia.org/wiki/Bitter_melon,,Momordica charantia +blackberry,https://en.wikipedia.org/wiki/Blackberry,,Rubus fruticosus +blackcurrant,https://en.wikipedia.org/wiki/Ribes,,Ribes spp. +borage,https://en.wikipedia.org/wiki/Borage,,Borago officinalis +breadfruit,https://en.wikipedia.org/wiki/Breadfruit,,Artocarpus altilis +broccoli,https://en.wikipedia.org/wiki/Broccoli,,Brassica oleracea +Brussels sprout,https://en.wikipedia.org/wiki/Brussels_sprout,,Brassica oleracea +buckwheat,https://en.wikipedia.org/wiki/Buckwheat,,Fagopyrum esculentum +cabbage,https://en.wikipedia.org/wiki/Cabbage,,Brassica oleracea +cape gooseberry,https://en.wikipedia.org/wiki/Physalis_peruviana,,Physalis peruviana +caper,https://en.wikipedia.org/wiki/Caper,,Capparis spinosa +cardoon,https://en.wikipedia.org/wiki/Cardoon,,Cynara cardunculus +carrot,https://en.wikipedia.org/wiki/Carrot,,Daucus carota +cassava,https://en.wikipedia.org/wiki/Cassava,,Manihot esculenta +catnip,https://en.wikipedia.org/wiki/Nepeta_cataria,,Nepeta cataria +cauliflower,https://en.wikipedia.org/wiki/Cauliflower,,Brassica oleracea +cayenne pepper,https://en.wikipedia.org/wiki/Cayenne_pepper,,Capsicum annuum +celeriac,https://en.wikipedia.org/wiki/Celeriac,,Apium graveolens var. rapaceum +celery,https://en.wikipedia.org/wiki/Celery,,Apium graveolens +chamomile,https://en.wikipedia.org/wiki/Matricaria_recutita,,Matricaria chamomila +chaya,https://en.wikipedia.org/wiki/Cnidoscolus_aconitifolius,,Cnidoscolus aconitifolius +chayote,https://en.wikipedia.org/wiki/Chayote,,Sechium edule +cherry,https://en.wikipedia.org/wiki/Cherry,,Prunus avium +chervil,https://en.wikipedia.org/wiki/Chervil,,Anthriscus cerefolium +chestnut,https://en.wikipedia.org/wiki/Chestnut,,Castanea spp. +chickpeas,https://en.wikipedia.org/wiki/Chickpea,,Cicer arietinum +chickweed,https://en.wikipedia.org/wiki/Stellaria,,Stellaria +chicory,https://en.wikipedia.org/wiki/Chicory,,Cichorium intybus +chinese cabbage,https://en.wikipedia.org/wiki/Chinese_cabbage,,Brassica rapa (pekinensis) +chives,https://en.wikipedia.org/wiki/Chives,,Allium schoenoprasum +cicely,https://en.wikipedia.org/wiki/Cicely,,Myrrhis odorata +citron,https://en.wikipedia.org/wiki/Citron,,Citrus medica +coconut,https://en.wikipedia.org/wiki/Coconut,,Cocos nucifera +collard greens,https://en.wikipedia.org/wiki/Collard_greens,,Brassica oleracea (acephala) +comfrey,https://en.wikipedia.org/wiki/Comfrey,,Symphytum officinale +coriander,https://en.wikipedia.org/wiki/Coriander,,Coriandrum sativum +corn,https://en.wikipedia.org/wiki/Corn,,Zea mays +corn salad,https://en.wikipedia.org/wiki/Corn_salad,,Valerianella locusta +cress,https://en.wikipedia.org/wiki/Garden_cress,,Lepidium sativum +cucumber,https://en.wikipedia.org/wiki/Cucumbers,,Cucumis sativus +cumin,https://en.wikipedia.org/wiki/Cumin,,Cuminum cyminum +cumquat,https://en.wikipedia.org/wiki/Kumquat,,Citrus japonica +curry leaf,https://en.wikipedia.org/wiki/Curry-leaf_Tree,,Murraya koenigii +curry plant,https://en.wikipedia.org/wiki/Helichrysum_italicum,,Helichrysum italicum +daikon,https://en.wikipedia.org/wiki/Daikon,,Raphanus sativus Longipinnatus group +dandelion,https://en.wikipedia.org/wiki/Dandelion,,Taraxacum officinale +dates,https://en.wikipedia.org/wiki/Date_%28fruit%29,,Phoenix dactylifera +desert lime,https://en.wikipedia.org/wiki/Citrus_glauca,,Citrus glauca +dill,https://en.wikipedia.org/wiki/Dill,,Anethum graveolens +dog rose,https://en.wikipedia.org/wiki/Rosa_canina,,Rosa canina +durian,https://en.wikipedia.org/wiki/Durian,,Durio +eggplant,https://en.wikipedia.org/wiki/Eggplant,,Solanum melongena +elderberry,https://en.wikipedia.org/wiki/Sambucus_nigra,,Sambucus nigra +endive,https://en.wikipedia.org/wiki/Endive,,Cichorium endivia +epazote,https://en.wikipedia.org/wiki/Epazote,,Dysphania ambrosioides +fava bean,https://en.wikipedia.org/wiki/Vicia_faba,,Vicia faba +feijoa,https://en.wikipedia.org/wiki/Acca_sellowiana,,Acca sellowiana +fennel,https://en.wikipedia.org/wiki/Fennel,,Foeniculum vulgare +fenugreek,https://en.wikipedia.org/wiki/Fenugreek,,Trigonella foenum-graecum +fiddlehead,https://en.wikipedia.org/wiki/Fiddlehead,,Pteridium aquilinum +fig,https://en.wikipedia.org/wiki/Common_fig,,Ficus carica +flax,https://en.wikipedia.org/wiki/Flax,,Linum usitatissimum +garlic,https://en.wikipedia.org/wiki/Garlic,,Allium sativum +garlic chives,https://en.wikipedia.org/wiki/Garlic_chives,,Allium tuberosum +ginger,https://en.wikipedia.org/wiki/Ginger,,Zingiber officinale +gooseberry,https://en.wikipedia.org/wiki/Gooseberry,,Ribes uva-crispa +grapefruit,https://en.wikipedia.org/wiki/Grapefruit,,Citrus paradisi +grapes,https://en.wikipedia.org/wiki/Grape,,Vitis spp. +guava,https://en.wikipedia.org/wiki/Guava,,Psidium spp. +habanero,https://en.wikipedia.org/wiki/Habanero,,Capsicum chinense +hibiscus,https://en.wikipedia.org/wiki/Hibiscus,,Hibiscus +horseradish,https://en.wikipedia.org/wiki/Horseradish,,Armoracia rusticana +jasmine,https://en.wikipedia.org/wiki/Jasmine,,Jasminum officinale +Jerusalem artichoke,https://en.wikipedia.org/wiki/Jerusalem_artichoke,,Helianthus tuberosus +jicama,https://en.wikipedia.org/wiki/Jicama,,Pachyrhizus erosus +juniper berry,https://en.wikipedia.org/wiki/Juniper_berry,,Juniperus communis +kaffir lime,https://en.wikipedia.org/wiki/Kaffir_lime,,Citrus x hystrix +kale,https://en.wikipedia.org/wiki/Kale,,Brassica oleracea (acephala) +kava,https://en.wikipedia.org/wiki/Kava,,Piper methysticum +kohlrabi,https://en.wikipedia.org/wiki/Kohlrabi,,Brassica oleracea (gongylodes) +lavender,https://en.wikipedia.org/wiki/Lavender,,Lavandula spp. +leek,https://en.wikipedia.org/wiki/Leeks,,Allium ampeloprasum var. porrum +lemon,https://en.wikipedia.org/wiki/Lemon,,Citrus limon +lemon balm,https://en.wikipedia.org/wiki/Lemon_balm,,Melissa officinalis +lemon myrtle,https://en.wikipedia.org/wiki/Backhousia_citriodora,,Backhousia citriodora +lemon verbena,https://en.wikipedia.org/wiki/Aloysia_citrodora,,Aloysia citrodora +lemongrass,https://en.wikipedia.org/wiki/Lemongrass,,Cymbopogon spp. +lentils,https://en.wikipedia.org/wiki/Lentil,,Lens culinaris +lettuce,https://en.wikipedia.org/wiki/Lettuce,,Lactuca sativa +licorice,https://en.wikipedia.org/wiki/Licorice,,Glycyrrhiza glabra +lillipilli,https://en.wikipedia.org/wiki/Syzygium_luehmannii,,Syzygium luehmannii +lima bean,https://en.wikipedia.org/wiki/Phaseolus_lunatus,,Phaseolus lunatus +lime,https://en.wikipedia.org/wiki/Lime_%28fruit%29,,Citrus spp. +lovage,https://en.wikipedia.org/wiki/Lovage,,Levisticum officinale +luffa,https://en.wikipedia.org/wiki/Luffa,,Luffa cylindrica +lupin bean,https://en.wikipedia.org/wiki/Lupin_bean,,Lupinus luteus +macadamia,https://en.wikipedia.org/wiki/Macadamia,,Macadamia +Malabar spinach,https://en.wikipedia.org/wiki/Basella_alba,,Basella alba +mandarin,https://en.wikipedia.org/wiki/Mandarin_orange,,Citrus reticulata +mango,https://en.wikipedia.org/wiki/Mango,,Mangifera spp. +maracuja,https://en.wikipedia.org/wiki/Maracuja,,Passiflora edulis +marjoram,https://en.wikipedia.org/wiki/Marjoram,,Origanum majorana +marshmallow,https://en.wikipedia.org/wiki/Althaea_officinalis,,Althaea officinalis +medlar,https://en.wikipedia.org/wiki/Mespilus_germanica,,Mespilus germanica +melon,https://en.wikipedia.org/wiki/Melon,,Cucumis melo +miner's lettuce,https://en.wikipedia.org/wiki/Claytonia_perfoliata,,Claytonia perfoliata +mint,https://en.wikipedia.org/wiki/Mentha_spicata,,Mentha spicata +mung bean,https://en.wikipedia.org/wiki/Mung_bean,,Vigna radiata +mustard,https://en.wikipedia.org/wiki/Mustard_plant,,Brassica juncea +nasturtium,https://en.wikipedia.org/wiki/Tropaeolum,,Tropaeloum spp. +New Zealand spinach,https://en.wikipedia.org/wiki/Tetragonia,,Tetragonia tetragonioides +nigella,https://en.wikipedia.org/wiki/Nigella_sativa,,Nigella sativa +oats,https://en.wikipedia.org/wiki/Oats,,Avena sativa +okra,https://en.wikipedia.org/wiki/Okra,,Abelmoschus esculentus +olive,https://en.wikipedia.org/wiki/Olive,,Olea europaea +onion,https://en.wikipedia.org/wiki/Onions,,Allium cepa +orange,https://en.wikipedia.org/wiki/Orange_%28fruit%29,,Citrus sinensis +oregano,https://en.wikipedia.org/wiki/Oregano,,Origanum vulgare +parsley,https://en.wikipedia.org/wiki/Parsley,,Petroselinum hortense +parsnip,https://en.wikipedia.org/wiki/Parsnip,,Pastinaca sativa +passion fruit,https://en.wikipedia.org/wiki/Passionfruit,,Passiflora edulis +pea,https://en.wikipedia.org/wiki/Pea,,Pisum sativum +peach,https://en.wikipedia.org/wiki/Peach,,Prunus persica +peach,https://en.wikipedia.org/wiki/Peach,,Prunus persica +peanut,https://en.wikipedia.org/wiki/Peanut,,Arachis hypogaea +pear,https://en.wikipedia.org/wiki/Pear,,Pyrus spp. +pearl millet,https://en.wikipedia.org/wiki/Pearl_millet,,Pennisetum glaucum +pecan,https://en.wikipedia.org/wiki/Pecan,,Carya illinoinensis +peppermint,https://en.wikipedia.org/wiki/Peppermint,,Mentha x piperita +Persian lime,https://en.wikipedia.org/wiki/Persian_lime,,Citrus latifolia +persimmon,https://en.wikipedia.org/wiki/Persimmon,,Diospyros spp. +pigeon pea,https://en.wikipedia.org/wiki/Pigeon_pea,,Cajanus cajan +pigface,https://en.wikipedia.org/wiki/Carpobrotus_glaucescens,,Carpobrotus glaucescens +pineapple,https://en.wikipedia.org/wiki/Pineapple,,Ananas comosus +pistachio,https://en.wikipedia.org/wiki/Pistachio,,Pistacia vera +plantain,https://en.wikipedia.org/wiki/Plantain,,Musa spp. +plum,https://en.wikipedia.org/wiki/Plum,,Prunus spp. +pomegranate,https://en.wikipedia.org/wiki/Pomegranate,,Punica granatum +pomelo,https://en.wikipedia.org/wiki/Pomelo,,Citrus maxima +potato,https://en.wikipedia.org/wiki/Potatoes,,Solanum tuberosum +prickly pear,https://en.wikipedia.org/wiki/Opuntia,,Opuntia +pumpkin,https://en.wikipedia.org/wiki/Pumpkin,,Cucurbita spp. +purslane,https://en.wikipedia.org/wiki/Portulaca_oleracea,,Portulaca oleracea +quandong,https://en.wikipedia.org/wiki/Santalum_acuminatum,,Santalum acuminatum +quince,https://en.wikipedia.org/wiki/Quince,,Cydonia oblonga +quinoa,https://en.wikipedia.org/wiki/Quinoa,,Chenopodium quinoa +radicchio,https://en.wikipedia.org/wiki/Radicchio,,Cichorium intybus +radish,https://en.wikipedia.org/wiki/Radish,,Raphanus sativus +rapeseed,https://en.wikipedia.org/wiki/Rapeseed,,Brassica napus +raspberry,https://en.wikipedia.org/wiki/Rubus_idaeus,,Rubus idaeus +rhubarb,https://en.wikipedia.org/wiki/Rhubarb,,Rheum rhabarbarum +rice,https://en.wikipedia.org/wiki/Rice,,Oryza sativa +rice bean,https://en.wikipedia.org/wiki/Ricebean,,Vigna umbellata +rose,https://en.wikipedia.org/wiki/Rose,,Rosa +roselle,https://en.wikipedia.org/wiki/Roselle_%28plant%29,,Hibiscus sabdariffa +rosemary,https://en.wikipedia.org/wiki/Rosemary,,Rosmarinus officinalis +rue,https://en.wikipedia.org/wiki/Common_Rue,,Ruta graveolens +runner bean,https://en.wikipedia.org/wiki/Runner_bean,,Phaseolus coccineus +rutabaga,https://en.wikipedia.org/wiki/Rutabaga,,Brassica napus Napobrassica group +rye,https://en.wikipedia.org/wiki/Rye,,Secale cereale +safflower,https://en.wikipedia.org/wiki/Safflower,,Carthamus tinctorius +saffron,https://en.wikipedia.org/wiki/Saffron,,Crocus sativus +sage,https://en.wikipedia.org/wiki/Salvia_officinalis,,Salvia officinalis +salad burnet,https://en.wikipedia.org/wiki/Salad_burnet,,Sanguisorba minor +salsify,https://en.wikipedia.org/wiki/Salsify,,Tragopogon porrifolius +samphire,https://en.wikipedia.org/wiki/Rock_samphire,,Crithmum maritimum +sassafras,https://en.wikipedia.org/wiki/Sassafras_albidum,,Sassafras albidum +sesame,https://en.wikipedia.org/wiki/Sesame,,Sesamum indicum +shallot,https://en.wikipedia.org/wiki/Shallot,,Allium cepa var. aggregatum +sorghum,https://en.wikipedia.org/wiki/Sorghum,,Sorghum spp. +sorrel,https://en.wikipedia.org/wiki/Sorrel,,Rumex acetosa +soursop,https://en.wikipedia.org/wiki/Soursop,,Annona muricata +soybean,https://en.wikipedia.org/wiki/Soybean,,Glycine max +spearmint,https://en.wikipedia.org/wiki/Mentha_spicata,,Mentha spicata +spinach,https://en.wikipedia.org/wiki/Spinach,,Spinacia oleracea +star anise,https://en.wikipedia.org/wiki/Star_anise,,Illicium verum +starfruit,https://en.wikipedia.org/wiki/Starfruit,,Averrhoa carambola +stevia,https://en.wikipedia.org/wiki/Stevia,,Stevia rebaudiana +strawberry,https://en.wikipedia.org/wiki/Strawberry,,Fragaria ananassa +summer savory,https://en.wikipedia.org/wiki/Summer_savory,,Satureja hortensis +sunflowers,https://en.wikipedia.org/wiki/Sunflower,,Helianthus annuus +sweet potato,https://en.wikipedia.org/wiki/Sweet_potato,,Ipomoea batatas +Swiss chard,https://en.wikipedia.org/wiki/Swiss_chard,,Beta vulgaris var. cicla +tamarillo,https://en.wikipedia.org/wiki/Tamarillo,,Solanum betaceum +tamarind,https://en.wikipedia.org/wiki/Tamarind,,Tamarindus indica +tangerine,https://en.wikipedia.org/wiki/Tangerine,,Citrus tangerina +tansy,https://en.wikipedia.org/wiki/Tansy,,Tanacetum vulgare +taro,https://en.wikipedia.org/wiki/Taro,,Colocasia esculenta +tarragon,https://en.wikipedia.org/wiki/Tarragon,,Artemisia dracunculus +thyme,https://en.wikipedia.org/wiki/Thyme,,Thymus mongolicus +tomatillo,https://en.wikipedia.org/wiki/Tomatillo,,Physalis philadelphica +tomato,https://en.wikipedia.org/wiki/Tomato,,Solanum lycopersicum +turmeric,https://en.wikipedia.org/wiki/Turmeric,,Curcuma longa +turnip,https://en.wikipedia.org/wiki/Turnip,,Brassica rapa var. rapa +urad bean,https://en.wikipedia.org/wiki/Urad_(bean),,Vigna mungo +valerian,https://en.wikipedia.org/wiki/Valerian_%28plant%29,,Valeriana officinalis +vanilla,https://en.wikipedia.org/wiki/Vanilla,,Vanilla planifolia +walnut,https://en.wikipedia.org/wiki/Walnut,,Juglans spp. +wasabi,https://en.wikipedia.org/wiki/Wasabi,,Wasabia japonica +watermelon,https://en.wikipedia.org/wiki/Watermelon,,Citrullus lanatus +wheat,https://en.wikipedia.org/wiki/Wheat,,Triticum spp. +winter savory,https://en.wikipedia.org/wiki/Winter_savory,,Satureja montana +wormwood,https://en.wikipedia.org/wiki/Artemisia_absinthium,,Artemisia absinthium +yam,https://en.wikipedia.org/wiki/Yam_(vegetable),,Dioscorea spp. +yardlong bean,https://en.wikipedia.org/wiki/Yardlong_bean,,Vigna unguiculata (sesquipedalis) +yarrow,https://en.wikipedia.org/wiki/Achillea_millefolium,,Achillea millefolium +zucchini,https://en.wikipedia.org/wiki/Zucchini,,Cucurbita pepo. +coffee,https://en.wikipedia.org/wiki/Coffee,,Coffea +tea,https://en.wikipedia.org/wiki/Tea,,Camellia sinensis diff --git a/db/seeds/crops-10-peppers.csv b/db/seeds/crops-10-peppers.csv index 55c3aff62..c0d231519 100644 --- a/db/seeds/crops-10-peppers.csv +++ b/db/seeds/crops-10-peppers.csv @@ -1,61 +1,61 @@ -Capsicum,Capsicum,http://en.wikipedia.org/wiki/Capsicum,,This is the top parent variety -- the entire family of all kinds of peppers -Capsicum annuum,Capsicum annuum,http://en.wikipedia.org/wiki/Capsicum_annuum,Capsicum, -Capsicum baccatum,Capsicum baccatum,http://en.wikipedia.org/wiki/Capsicum_baccatum,Capsicum, -Capsicum chinense,Capsicum chinense,http://en.wikipedia.org/wiki/Capsicum_chinense,Capsicum, -rocoto,Capsicum pubescens,http://en.wikipedia.org/wiki/Capsicum_pubescens,Capsicum,AKA locoto -Capsicum frutescens,Capsicum frutescens,http://en.wikipedia.org/wiki/Capsicum_frutescens,Capsicum, -Aleppo pepper,,http://en.wikipedia.org/wiki/Aleppo_pepper,Capsicum annuum,"AKA pul biber, halaby pepper" -Anaheim pepper,,http://en.wikipedia.org/wiki/Anaheim_pepper,Capsicum annuum,"AKA New Mexico pepper, California chili, Magdalena chili" -banana pepper,,http://en.wikipedia.org/wiki/Banana_pepper,Capsicum annuum,"AKA yellow wax pepper, banana chili" -bell pepper,,http://en.wikipedia.org/wiki/Bell_pepper,Capsicum annuum,"AKA capsicum, sweet pepper, pepper, poivron, peperoni, piment" -bird's eye chili,,http://en.wikipedia.org/wiki/Bird%27s_eye_chili,Capsicum annuum,"AKA Thai chili pepper, bird's chili" -cascabel chili,,http://en.wikipedia.org/wiki/Cascabel_chili,Capsicum annuum,"AKA rattle chile, bola chile, chile bola" -cayenne pepper,,http://en.wikipedia.org/wiki/Cayenne_pepper,Capsicum annuum,"AKA Guinea spice, cow-horn pepper, aleva, bird pepper, red pepper" -pasilla pepper,,http://en.wikipedia.org/wiki/Pasilla,Capsicum annuum,"AKA chilaca pepper, chile negro" -chiltepin pepper,Capsicum annuum var. glabriusculum,http://en.wikipedia.org/wiki/Capsicum_annuum_var._glabriusculum,Capsicum annuum,"AKA wild chiltepin, chiltepe, chile tepin, turkey pepper, bird’s eye pepper, bird pepper" -Chungyang red pepper,,http://en.wikipedia.org/wiki/Chungyang_Red_Pepper,Capsicum annuum, -cubanelle pepper,,http://en.wikipedia.org/wiki/Cubanelle,Capsicum annuum, -chile de árbol pepper,,http://en.wikipedia.org/wiki/Chile_de_%C3%A1rbol,Capsicum annuum,"AKA bird's beak chile, rat's tail chile" -dundicut,,http://en.wikipedia.org/wiki/Dundicut,Capsicum annuum,AKA lal mirch -facing heaven pepper,Capsicum annuum var. conoides,http://en.wikipedia.org/wiki/Facing_heaven_pepper,Capsicum annuum, -Fresno pepper,,http://en.wikipedia.org/wiki/Fresno_pepper,Capsicum annuum, -guajillo pepper,,http://en.wikipedia.org/wiki/Guajillo_chili,Capsicum annuum,"AKA guajillo chili, guajillo chilli, chile guajillo" -Guntur Sannam chili,Capsicum Annuum var. Longhum,http://en.wikipedia.org/wiki/Guntur_Sannam,Capsicum annuum, -Hungarian wax pepper,,http://en.wikipedia.org/wiki/Hungarian_wax_pepper,Capsicum annuum, -Italian sweet pepper,,http://en.wikipedia.org/wiki/Italian_sweet_pepper,Capsicum annuum, -jalapeño pepper,,http://en.wikipedia.org/wiki/Jalape%C3%B1o,Capsicum annuum, -shishito pepper,,http://en.wikipedia.org/wiki/Shishito,Capsicum annuum, -medusa pepper,,http://en.wikipedia.org/wiki/Medusa_pepper,Capsicum annuum, -mulato pepper,,http://en.wikipedia.org/wiki/Mulato_pepper,Capsicum annuum, -peter pepper,Capsicum annuum var. annuum,http://en.wikipedia.org/wiki/Peter_pepper,Capsicum annuum,AKA chilli willy pepper -peperoncini pepper,,http://en.wikipedia.org/wiki/Peperoncini,Capsicum annuum,"AKA friggitello, peperone" -pequin pepper,"Capsicum annuum var. glabriusculum -",http://en.wikipedia.org/wiki/Pequin_pepper,Capsicum annuum,AKA piquin -pimento pepper,,http://en.wikipedia.org/wiki/Pimiento,Capsicum annuum,"AKA cherry pepper, pimiento pepper" -poblano pepper,,http://en.wikipedia.org/wiki/Poblano,Capsicum annuum, -Santa Fe Grande pepper,,http://en.wikipedia.org/wiki/Santa_Fe_Grande_pepper,Capsicum annuum,"AKA yellow hot chili pepper, guero chili pepper" -serrano pepper,,http://en.wikipedia.org/wiki/Serrano_pepper,Capsicum annuum, -bishop's crown pepper,Capsicum baccatum var. pendulum,http://en.wikipedia.org/wiki/Bishop%27s_Crown,Capsicum baccatum,AKA Christmas bell -lemon drop pepper,,http://en.wikipedia.org/wiki/Lemon_drop_%28pepper%29,Capsicum baccatum,"AKA ají limon, kellu uchu, hot lemon" -peppadew pepper,,http://en.wikipedia.org/wiki/Peppadew,Capsicum baccatum, -Brazilian starfish,,http://en.wikipedia.org/wiki/Capsicum_baccatum,Capsicum baccatum, -wild baccatum,,http://en.wikipedia.org/wiki/Capsicum_baccatum,Capsicum baccatum, -adjuma pepper,,http://en.wikipedia.org/wiki/Adjuma,Capsicum chinense,"AKA adjoema, aji umba, ojemma" -ají dulce pepper,,http://en.wikipedia.org/wiki/Aj%C3%AD_dulce,Capsicum chinense,"AKA ajicito, ajice, rubra, biquinho" -datil pepper,,http://en.wikipedia.org/wiki/Datil_pepper,Capsicum chinense, -fatalii pepper,,http://en.wikipedia.org/wiki/Fatalii,Capsicum chinense, -Madame Jeanette pepper,,http://en.wikipedia.org/wiki/Madame_Jeanette,Capsicum chinense, -habanero pepper,,http://en.wikipedia.org/wiki/Habanero,Capsicum chinense,AKA habañero -black habanero pepper,,http://en.wikipedia.org/wiki/Habanero,Capsicum chinense, -red savino pepper,,http://en.wikipedia.org/wiki/Red_Savina_pepper,Capsicum chinense, -bhut jolokia pepper,,http://en.wikipedia.org/wiki/Bhut_Jolokia,Capsicum chinense,"AKA ghost pepper, ghost chili pepper, red naga chilli, ghost chilli, naga jolokia" -Scotch bonnet pepper,,http://en.wikipedia.org/wiki/Scotch_bonnet_%28pepper%29,Capsicum chinense,"AKA boabs bonnet, Scotty bons, Bonney peppers, Caribbean red peppers, ball of fire" -cachucha pepper,,http://en.wikipedia.org/wiki/Scotch_bonnet_%28pepper%29,Capsicum chinense, -Trinidad scorpion butch T pepper,,http://en.wikipedia.org/wiki/Trinidad_Scorpion_Butch_T_pepper,Capsicum chinense, -Trinidad Moruga scorpion pepper,,http://en.wikipedia.org/wiki/Trinidad_Moruga_Scorpion,Capsicum chinense, -Hainan yellow lantern,,http://en.wikipedia.org/wiki/Hainan_Yellow_Lantern_Chili,Capsicum chinense,AKA yellow emperor chili -piri-piri pepper,,http://en.wikipedia.org/wiki/Piri_piri,Capsicum frutescens,"AKA African bird's eye pepper, peri peri, pili pili" -Tabasco pepper,,http://en.wikipedia.org/wiki/Tabasco_pepper,Capsicum frutescens, -malagueta pepper,,http://en.wikipedia.org/wiki/Malagueta_pepper,Capsicum frutescens, -siling labuyo pepper,,http://en.wikipedia.org/wiki/Siling_labuyo,Capsicum frutescens,"AKA chileng bundok, siling palay, pasitis, pasite, katumbal, kitikot, siling kolikot, silit-diablo, lada, rimorimo, paktin" -kambuzi,,http://en.wikipedia.org/wiki/Kambuzi,Capsicum frutescens, +Capsicum,http://en.wikipedia.org/wiki/Capsicum,,Capsicum +Capsicum annuum,http://en.wikipedia.org/wiki/Capsicum_annuum,Capsicum,Capsicum annuum +Capsicum baccatum,http://en.wikipedia.org/wiki/Capsicum_baccatum,Capsicum,Capsicum baccatum +Capsicum chinense,http://en.wikipedia.org/wiki/Capsicum_chinense,Capsicum,Capsicum chinense +rocoto,http://en.wikipedia.org/wiki/Capsicum_pubescens,Capsicum,Capsicum pubescens +Capsicum frutescens,http://en.wikipedia.org/wiki/Capsicum_frutescens,Capsicum,Capsicum frutescens +Aleppo pepper,http://en.wikipedia.org/wiki/Aleppo_pepper,Capsicum annuum, +Anaheim pepper,http://en.wikipedia.org/wiki/Anaheim_pepper,Capsicum annuum, +banana pepper,http://en.wikipedia.org/wiki/Banana_pepper,Capsicum annuum, +bell pepper,http://en.wikipedia.org/wiki/Bell_pepper,Capsicum annuum, +bird's eye chili,http://en.wikipedia.org/wiki/Bird%27s_eye_chili,Capsicum annuum, +cascabel chili,http://en.wikipedia.org/wiki/Cascabel_chili,Capsicum annuum, +cayenne pepper,http://en.wikipedia.org/wiki/Cayenne_pepper,Capsicum annuum, +pasilla pepper,http://en.wikipedia.org/wiki/Pasilla,Capsicum annuum, +chiltepin pepper,http://en.wikipedia.org/wiki/Capsicum_annuum_var._glabriusculum,Capsicum annuum,Capsicum annuum var. glabriusculum +Chungyang red pepper,http://en.wikipedia.org/wiki/Chungyang_Red_Pepper,Capsicum annuum, +cubanelle pepper,http://en.wikipedia.org/wiki/Cubanelle,Capsicum annuum, +chile de árbol pepper,http://en.wikipedia.org/wiki/Chile_de_%C3%A1rbol,Capsicum annuum, +dundicut,http://en.wikipedia.org/wiki/Dundicut,Capsicum annuum, +facing heaven pepper,http://en.wikipedia.org/wiki/Facing_heaven_pepper,Capsicum annuum,Capsicum annuum var. conoides +Fresno pepper,http://en.wikipedia.org/wiki/Fresno_pepper,Capsicum annuum, +guajillo pepper,http://en.wikipedia.org/wiki/Guajillo_chili,Capsicum annuum, +Guntur Sannam chili,http://en.wikipedia.org/wiki/Guntur_Sannam,Capsicum annuum,Capsicum Annuum var. Longhum +Hungarian wax pepper,http://en.wikipedia.org/wiki/Hungarian_wax_pepper,Capsicum annuum, +Italian sweet pepper,http://en.wikipedia.org/wiki/Italian_sweet_pepper,Capsicum annuum, +jalapeño pepper,http://en.wikipedia.org/wiki/Jalape%C3%B1o,Capsicum annuum, +shishito pepper,http://en.wikipedia.org/wiki/Shishito,Capsicum annuum, +medusa pepper,http://en.wikipedia.org/wiki/Medusa_pepper,Capsicum annuum, +mulato pepper,http://en.wikipedia.org/wiki/Mulato_pepper,Capsicum annuum, +peter pepper,http://en.wikipedia.org/wiki/Peter_pepper,Capsicum annuum,Capsicum annuum var. annuum +peperoncini pepper,http://en.wikipedia.org/wiki/Peperoncini,Capsicum annuum, +pequin pepper,http://en.wikipedia.org/wiki/Pequin_pepper,Capsicum annuum,"Capsicum annuum var. glabriusculum +" +pimento pepper,http://en.wikipedia.org/wiki/Pimiento,Capsicum annuum, +poblano pepper,http://en.wikipedia.org/wiki/Poblano,Capsicum annuum, +Santa Fe Grande pepper,http://en.wikipedia.org/wiki/Santa_Fe_Grande_pepper,Capsicum annuum, +serrano pepper,http://en.wikipedia.org/wiki/Serrano_pepper,Capsicum annuum, +bishop's crown pepper,http://en.wikipedia.org/wiki/Bishop%27s_Crown,Capsicum baccatum,Capsicum baccatum var. pendulum +lemon drop pepper,http://en.wikipedia.org/wiki/Lemon_drop_%28pepper%29,Capsicum baccatum, +peppadew pepper,http://en.wikipedia.org/wiki/Peppadew,Capsicum baccatum, +Brazilian starfish,http://en.wikipedia.org/wiki/Capsicum_baccatum,Capsicum baccatum, +wild baccatum,http://en.wikipedia.org/wiki/Capsicum_baccatum,Capsicum baccatum, +adjuma pepper,http://en.wikipedia.org/wiki/Adjuma,Capsicum chinense, +ají dulce pepper,http://en.wikipedia.org/wiki/Aj%C3%AD_dulce,Capsicum chinense, +datil pepper,http://en.wikipedia.org/wiki/Datil_pepper,Capsicum chinense, +fatalii pepper,http://en.wikipedia.org/wiki/Fatalii,Capsicum chinense, +Madame Jeanette pepper,http://en.wikipedia.org/wiki/Madame_Jeanette,Capsicum chinense, +habanero pepper,http://en.wikipedia.org/wiki/Habanero,Capsicum chinense, +black habanero pepper,http://en.wikipedia.org/wiki/Habanero,Capsicum chinense, +red savino pepper,http://en.wikipedia.org/wiki/Red_Savina_pepper,Capsicum chinense, +bhut jolokia pepper,http://en.wikipedia.org/wiki/Bhut_Jolokia,Capsicum chinense, +Scotch bonnet pepper,http://en.wikipedia.org/wiki/Scotch_bonnet_%28pepper%29,Capsicum chinense, +cachucha pepper,http://en.wikipedia.org/wiki/Scotch_bonnet_%28pepper%29,Capsicum chinense, +Trinidad scorpion butch T pepper,http://en.wikipedia.org/wiki/Trinidad_Scorpion_Butch_T_pepper,Capsicum chinense, +Trinidad Moruga scorpion pepper,http://en.wikipedia.org/wiki/Trinidad_Moruga_Scorpion,Capsicum chinense, +Hainan yellow lantern,http://en.wikipedia.org/wiki/Hainan_Yellow_Lantern_Chili,Capsicum chinense, +piri-piri pepper,http://en.wikipedia.org/wiki/Piri_piri,Capsicum frutescens, +Tabasco pepper,http://en.wikipedia.org/wiki/Tabasco_pepper,Capsicum frutescens, +malagueta pepper,http://en.wikipedia.org/wiki/Malagueta_pepper,Capsicum frutescens, +siling labuyo pepper,http://en.wikipedia.org/wiki/Siling_labuyo,Capsicum frutescens, +kambuzi,http://en.wikipedia.org/wiki/Kambuzi,Capsicum frutescens, diff --git a/db/seeds/crops-11-tomatoes.csv b/db/seeds/crops-11-tomatoes.csv index acb39a039..b56ed850a 100644 --- a/db/seeds/crops-11-tomatoes.csv +++ b/db/seeds/crops-11-tomatoes.csv @@ -1,41 +1,41 @@ -adoration tomato,,https://en.wikipedia.org/wiki/Adoration_%28Tomato%29,tomato -alicante tomato,,https://en.wikipedia.org/wiki/Alicante_%28tomato%29,tomato -Amish paste tomato,,http://en.wikipedia.org/wiki/Amish_Paste,tomato -Aunt Ruby's German green tomato,,http://en.wikipedia.org/wiki/Aunt_Ruby%27s_German_Green,tomato -azoychka tomato,,https://en.wikipedia.org/wiki/Azoychka%28Tomato%29,tomato -beefsteak tomato,,https://en.wikipedia.org/wiki/Beefsteak_(tomato),tomato -better boy tomato,,https://en.wikipedia.org/wiki/Better_Boy,tomato -big rainbow tomato,,https://en.wikipedia.org/wiki/Big_Rainbow_(Tomato),tomato -Blaby special tomato,,https://en.wikipedia.org/wiki/Blaby_Special_(Tomato),tomato -black krim tomato,,https://en.wikipedia.org/wiki/Black_Krim_%28tomato%29,tomato -brandywine tomato,,https://en.wikipedia.org/wiki/Brandywine_(tomato),tomato -campari tomato,,https://en.wikipedia.org/wiki/Campari_tomato,tomato -celebrity tomato,,http://en.wikipedia.org/wiki/Celebrity_(tomato),tomato -Cherokee purple tomato,,https://en.wikipedia.org/wiki/Cherokee_purple,tomato -cherry tomato,Solanum lycopersicum var. cerasiforme,http://en.wikipedia.org/wiki/Cherry_tomato,tomato -currant tomato,solanum pimpinellifolium,https://en.wikipedia.org/wiki/Solanum_pimpinellifolium, -early girl tomato,,https://en.wikipedia.org/wiki/Early_Girl,tomato -Fourth of July tomato,,https://en.wikipedia.org/wiki/Fourth_of_July_(tomato_variety),tomato -garden peach tomato,,https://en.wikipedia.org/wiki/Garden_peach_tomato,tomato -grape tomato,,http://en.wikipedia.org/wiki/Grape_tomato,tomato -green zebra tomato,,https://en.wikipedia.org/wiki/Green_Zebra,tomato -Hanover tomato,,http://en.wikipedia.org/wiki/Hanover_tomato,tomato -hillbilly tomato,,http://en.wikipedia.org/wiki/Hillbilly_(tomato),tomato -jubilee tomato,,http://en.wikipedia.org/wiki/Jubilee_(tomato),tomato -lillian's yellow tomato,,http://en.wikipedia.org/wiki/Lillian%27s_Yellow_(tomato),tomato -marglobe tomato,,http://en.wikipedia.org/wiki/Marglobe,tomato -Matt's wild cherry tomato,,http://en.wikipedia.org/wiki/Matt%27s_Wild_Cherry,cherry tomato -mortgage lifter tomato,,http://en.wikipedia.org/wiki/Mortgage_Lifter,tomato -Mr. Stripey tomato,,http://en.wikipedia.org/wiki/Mr._Stripey,tomato -pear tomato,,http://en.wikipedia.org/wiki/Pear_tomato,tomato -Roma tomato,,http://en.wikipedia.org/wiki/Roma_tomato,tomato -San Marzano tomato,,http://en.wikipedia.org/wiki/San_Marzano_tomato,tomato -Santorini tomato,,http://en.wikipedia.org/wiki/Santorini_(tomato),cherry tomato -stupice tomato,,http://en.wikipedia.org/wiki/Super_Sweet_100,tomato -super sweet 100 tomato,,http://en.wikipedia.org/wiki/Super_Sweet_100,cherry tomato -three sisters tomato,,http://en.wikipedia.org/wiki/Three_Sisters_(tomato),tomato -tigerella tomato,,http://en.wikipedia.org/wiki/Tigerella,tomato -tomaccio tomato,,http://en.wikipedia.org/wiki/Tomaccio_(tomato),cherry tomato -tomberry,,http://en.wikipedia.org/wiki/Tomberry,tomato -traveller tomato,,http://en.wikipedia.org/wiki/Traveller_(tomato),tomato -white queen tomato,,http://en.wikipedia.org/wiki/White_Queen_tomato,tomato +adoration tomato,https://en.wikipedia.org/wiki/Adoration_%28Tomato%29,tomato, +alicante tomato,https://en.wikipedia.org/wiki/Alicante_%28tomato%29,tomato, +Amish paste tomato,http://en.wikipedia.org/wiki/Amish_Paste,tomato, +Aunt Ruby's German green tomato,http://en.wikipedia.org/wiki/Aunt_Ruby%27s_German_Green,tomato, +azoychka tomato,https://en.wikipedia.org/wiki/Azoychka%28Tomato%29,tomato, +beefsteak tomato,https://en.wikipedia.org/wiki/Beefsteak_(tomato),tomato, +better boy tomato,https://en.wikipedia.org/wiki/Better_Boy,tomato, +big rainbow tomato,https://en.wikipedia.org/wiki/Big_Rainbow_(Tomato),tomato, +Blaby special tomato,https://en.wikipedia.org/wiki/Blaby_Special_(Tomato),tomato, +black krim tomato,https://en.wikipedia.org/wiki/Black_Krim_%28tomato%29,tomato, +brandywine tomato,https://en.wikipedia.org/wiki/Brandywine_(tomato),tomato, +campari tomato,https://en.wikipedia.org/wiki/Campari_tomato,tomato, +celebrity tomato,http://en.wikipedia.org/wiki/Celebrity_(tomato),tomato, +Cherokee purple tomato,https://en.wikipedia.org/wiki/Cherokee_purple,tomato, +cherry tomato,http://en.wikipedia.org/wiki/Cherry_tomato,tomato,Solanum lycopersicum var. cerasiforme +currant tomato,https://en.wikipedia.org/wiki/Solanum_pimpinellifolium,,solanum pimpinellifolium +early girl tomato,https://en.wikipedia.org/wiki/Early_Girl,tomato, +Fourth of July tomato,https://en.wikipedia.org/wiki/Fourth_of_July_(tomato_variety),tomato, +garden peach tomato,https://en.wikipedia.org/wiki/Garden_peach_tomato,tomato, +grape tomato,http://en.wikipedia.org/wiki/Grape_tomato,tomato, +green zebra tomato,https://en.wikipedia.org/wiki/Green_Zebra,tomato, +Hanover tomato,http://en.wikipedia.org/wiki/Hanover_tomato,tomato, +hillbilly tomato,http://en.wikipedia.org/wiki/Hillbilly_(tomato),tomato, +jubilee tomato,http://en.wikipedia.org/wiki/Jubilee_(tomato),tomato, +lillian's yellow tomato,http://en.wikipedia.org/wiki/Lillian%27s_Yellow_(tomato),tomato, +marglobe tomato,http://en.wikipedia.org/wiki/Marglobe,tomato, +Matt's wild cherry tomato,http://en.wikipedia.org/wiki/Matt%27s_Wild_Cherry,cherry tomato, +mortgage lifter tomato,http://en.wikipedia.org/wiki/Mortgage_Lifter,tomato, +Mr. Stripey tomato,http://en.wikipedia.org/wiki/Mr._Stripey,tomato, +pear tomato,http://en.wikipedia.org/wiki/Pear_tomato,tomato, +Roma tomato,http://en.wikipedia.org/wiki/Roma_tomato,tomato, +San Marzano tomato,http://en.wikipedia.org/wiki/San_Marzano_tomato,tomato, +Santorini tomato,http://en.wikipedia.org/wiki/Santorini_(tomato),cherry tomato, +stupice tomato,http://en.wikipedia.org/wiki/Super_Sweet_100,tomato, +super sweet 100 tomato,http://en.wikipedia.org/wiki/Super_Sweet_100,cherry tomato, +three sisters tomato,http://en.wikipedia.org/wiki/Three_Sisters_(tomato),tomato, +tigerella tomato,http://en.wikipedia.org/wiki/Tigerella,tomato, +tomaccio tomato,http://en.wikipedia.org/wiki/Tomaccio_(tomato),cherry tomato, +tomberry,http://en.wikipedia.org/wiki/Tomberry,tomato, +traveller tomato,http://en.wikipedia.org/wiki/Traveller_(tomato),tomato, +white queen tomato,http://en.wikipedia.org/wiki/White_Queen_tomato,tomato, diff --git a/spec/models/crop_spec.rb b/spec/models/crop_spec.rb index 661a688a3..1f44f4a89 100644 --- a/spec/models/crop_spec.rb +++ b/spec/models/crop_spec.rb @@ -398,9 +398,8 @@ describe Crop do expect(tomato.scientific_names.size).to eq 1 # shouldn't increase now end - it "loads the simplest possible crop" do - tomato_row = "tomato,,http://en.wikipedia.org/wiki/Tomato" + tomato_row = "tomato,http://en.wikipedia.org/wiki/Tomato" CSV.parse(tomato_row) do |row| Crop.create_from_csv(row) @@ -413,7 +412,7 @@ describe Crop do end it "loads a crop with a scientific name" do - tomato_row = "tomato,Solanum lycopersicum,http://en.wikipedia.org/wiki/Tomato" + tomato_row = "tomato,http://en.wikipedia.org/wiki/Tomato,,Solanum lycopersicum" CSV.parse(tomato_row) do |row| Crop.create_from_csv(row) @@ -427,7 +426,7 @@ describe Crop do it "loads a crop with a parent" do parent = FactoryGirl.create(:crop, :name => 'parent') - tomato_row = "tomato,,http://en.wikipedia.org/wiki/Tomato,parent" + tomato_row = "tomato,http://en.wikipedia.org/wiki/Tomato,parent" CSV.parse(tomato_row) do |row| Crop.create_from_csv(row) @@ -438,7 +437,7 @@ describe Crop do end it "doesn't add unnecessary duplicate crops" do - tomato_row = "tomato,Solanum lycopersicum,http://en.wikipedia.org/wiki/Tomato" + tomato_row = "tomato,http://en.wikipedia.org/wiki/Tomato,,Solanum lycopersicum" CSV.parse(tomato_row) do |row| Crop.create_from_csv(row) From 13c98eac895c8694002299b0b0429f070a90839f Mon Sep 17 00:00:00 2001 From: Yoong Kang Lim Date: Sun, 30 Nov 2014 15:14:56 +1100 Subject: [PATCH 24/38] Wrapped tests around context blocks to clarify the purpose of the tests. --- spec/models/member_spec.rb | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/spec/models/member_spec.rb b/spec/models/member_spec.rb index 5594c9dbd..b15f022fc 100644 --- a/spec/models/member_spec.rb +++ b/spec/models/member_spec.rb @@ -389,20 +389,24 @@ describe 'member' do @follow = @member1.follows.create(:follower_id => @member1.id, :followed_id => @member2.id) end - it 'detects that member is already following a member' do - expect(@member1.already_following?(@member2)).to eq true + context 'already_following' do + it 'detects that member is already following a member' do + expect(@member1.already_following?(@member2)).to eq true + end + + it 'detects that member is not already following a member' do + expect(@member1.already_following?(@member3)).to eq false + end end - it 'detects that member is not already following a member' do - expect(@member1.already_following?(@member3)).to eq false - end + context 'get_follow' do + it 'gets the correct follow for a followed member' do + expect(@member1.get_follow(@member2).id).to eq @follow.id + end - it 'gets the correct follow for a followed member' do - expect(@member1.get_follow(@member2).id).to eq @follow.id - end - - it 'returns nil for a member that is not followed' do - expect(@member1.get_follow(@member3)).to be_nil + it 'returns nil for a member that is not followed' do + expect(@member1.get_follow(@member3)).to be_nil + end end end From 2036a0f2e9e58c622285140eb24e7b643984895e Mon Sep 17 00:00:00 2001 From: Yoong Kang Lim Date: Sun, 30 Nov 2014 15:18:13 +1100 Subject: [PATCH 25/38] Used environment variable for site name instead --- app/models/follow.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/follow.rb b/app/models/follow.rb index 55b2ce95c..f8767c10c 100644 --- a/app/models/follow.rb +++ b/app/models/follow.rb @@ -9,7 +9,7 @@ class Follow < ActiveRecord::Base :recipient_id => self.followed_id, :sender_id => self.follower_id, :subject => "#{self.follower.login_name} is now following you", - :body => "#{self.follower.login_name} just followed you on Growstuff. " + :body => "#{self.follower.login_name} just followed you on #{ENV["GROWSTUFF_SITE_NAME"]}. " ) end From 7ddaca6e11faeb496cc88fcad9db6359fdd39fec Mon Sep 17 00:00:00 2001 From: Yoong Kang Lim Date: Sun, 30 Nov 2014 15:19:50 +1100 Subject: [PATCH 26/38] Use .size instead of .count --- app/views/members/_stats.html.haml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/views/members/_stats.html.haml b/app/views/members/_stats.html.haml index 0929e5998..b6e52873d 100644 --- a/app/views/members/_stats.html.haml +++ b/app/views/members/_stats.html.haml @@ -3,34 +3,34 @@ %ul %li - if member.plantings.count > 0 - = link_to pluralize(member.plantings.count, "planting"), plantings_by_owner_path(:owner => member) + = link_to pluralize(member.plantings.size, "planting"), plantings_by_owner_path(:owner => member) - else 0 plantings %li - if member.harvests.count > 0 - = link_to pluralize(member.harvests.count, "harvest"), harvests_by_owner_path(:owner => member) + = link_to pluralize(member.harvests.size, "harvest"), harvests_by_owner_path(:owner => member) - else 0 harvests %li - if member.seeds.count > 0 - = link_to pluralize(member.seeds.count, "seeds"), seeds_by_owner_path(:owner => member) + = link_to pluralize(member.seeds.size, "seeds"), seeds_by_owner_path(:owner => member) - else 0 seeds %li - if member.posts.count > 0 - = link_to pluralize(member.posts.count, "post"), posts_by_author_path(:author => member) + = link_to pluralize(member.posts.size, "post"), posts_by_author_path(:author => member) - else 0 posts %li - if member.followed.count > 0 - = link_to pluralize(member.followed.count, "follow"), member_follows_path(member) + = link_to pluralize(member.followed.size, "follow"), member_follows_path(member) - else 0 following %li - if member.followers.count > 0 - = link_to pluralize(member.followers.count, "follower"), member_followers_path(member) + = link_to pluralize(member.followers.size, "follower"), member_followers_path(member) - else 0 followers From 73d6b5065b29d4937c1b3f0d7815073049f4165c Mon Sep 17 00:00:00 2001 From: Yoong Kang Lim Date: Sun, 30 Nov 2014 15:25:48 +1100 Subject: [PATCH 27/38] Use factorygirl aliases --- spec/factories/follows.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/factories/follows.rb b/spec/factories/follows.rb index d9bd13616..6de32b7a1 100644 --- a/spec/factories/follows.rb +++ b/spec/factories/follows.rb @@ -1,7 +1,7 @@ FactoryGirl.define do factory :follow do - follower_id 1 - followed_id 2 + follower + followed end end From 844791ead9b1d4f4e8b88965e61eafe9ad08a655 Mon Sep 17 00:00:00 2001 From: Skud Date: Sun, 30 Nov 2014 15:48:58 +1100 Subject: [PATCH 28/38] Allow multiple comma-separated scientific names --- app/models/crop.rb | 38 +++++++++++++++++---------------- spec/models/crop_spec.rb | 45 ++++++++++++++++++++++++++++++++-------- 2 files changed, 56 insertions(+), 27 deletions(-) diff --git a/app/models/crop.rb b/app/models/crop.rb index 5f4758366..f2a182472 100644 --- a/app/models/crop.rb +++ b/app/models/crop.rb @@ -127,7 +127,7 @@ class Crop < ActiveRecord::Base # - scientific name (optional, can be picked up from parent if it has one) def Crop.create_from_csv(row) - name,en_wikipedia_url,parent,scientific_name = row + name,en_wikipedia_url,parent,scientific_names = row cropbot = Member.find_by_login_name('cropbot') raise "cropbot account not found: run rake db:seed" unless cropbot @@ -147,31 +147,33 @@ class Crop < ActiveRecord::Base end end - crop.add_scientific_name_from_csv(scientific_name) + crop.add_scientific_names_from_csv(scientific_names) end - def add_scientific_name_from_csv(scientific_name) - name_to_add = nil - if ! scientific_name.blank? # i.e. we actually passed one in, which isn't a given - name_to_add = scientific_name - elsif parent && parent.default_scientific_name - name_to_add = parent.default_scientific_name + def add_scientific_names_from_csv(scientific_names) + names_to_add = [] + if ! scientific_names.blank? # i.e. we actually passed something in, which isn't a given + names_to_add = scientific_names.split(%r{,\s*}) + elsif parent && parent.scientific_names.size > 0 # pick up from parent + names_to_add = parent.scientific_names.map{|s| s.scientific_name} else logger.warn("Warning: no scientific name (not even on parent crop) for #{self}") end - if name_to_add - if scientific_names.exists?(:scientific_name => name_to_add) - logger.warn("Warning: skipping duplicate scientific name #{name_to_add} for #{self}") - else - cropbot = Member.find_by_login_name('cropbot') - raise "cropbot account not found: run rake db:seed" unless cropbot + if names_to_add.size > 0 + names_to_add.each do |n| + if self.scientific_names.exists?(:scientific_name => n) + logger.warn("Warning: skipping duplicate scientific name #{n} for #{self}") + else + cropbot = Member.find_by_login_name('cropbot') + raise "cropbot account not found: run rake db:seed" unless cropbot - scientific_names.create( - :scientific_name => name_to_add, - :creator_id => cropbot.id - ) + self.scientific_names.create( + :scientific_name => n, + :creator_id => cropbot.id + ) + end end end diff --git a/spec/models/crop_spec.rb b/spec/models/crop_spec.rb index 1f44f4a89..0c41a343f 100644 --- a/spec/models/crop_spec.rb +++ b/spec/models/crop_spec.rb @@ -354,14 +354,14 @@ describe Crop do it "adds a scientific name to a crop that has none" do tomato = FactoryGirl.create(:tomato) expect(tomato.scientific_names.size).to eq 0 - tomato.add_scientific_name_from_csv("Foo bar") + tomato.add_scientific_names_from_csv("Foo bar") expect(tomato.scientific_names.size).to eq 1 expect(tomato.default_scientific_name).to eq "Foo bar" end it "picks up scientific name from parent crop if available" do parent = FactoryGirl.create(:crop, :name => 'parent crop') - parent.add_scientific_name_from_csv("Parentis cropis") + parent.add_scientific_names_from_csv("Parentis cropis") parent.save parent.reload @@ -369,32 +369,32 @@ describe Crop do expect(tomato.parent).to eq parent expect(tomato.parent.default_scientific_name).to eq "Parentis cropis" - tomato.add_scientific_name_from_csv('') + tomato.add_scientific_names_from_csv('') expect(tomato.default_scientific_name).to eq "Parentis cropis" end it "doesn't add a duplicate scientific name" do tomato = FactoryGirl.create(:tomato) expect(tomato.scientific_names.size).to eq 0 - tomato.add_scientific_name_from_csv("Foo bar") + tomato.add_scientific_names_from_csv("Foo bar") expect(tomato.scientific_names.size).to eq 1 - tomato.add_scientific_name_from_csv("Foo bar") + tomato.add_scientific_names_from_csv("Foo bar") expect(tomato.scientific_names.size).to eq 1 # shouldn't increase - tomato.add_scientific_name_from_csv("Baz quux") + tomato.add_scientific_names_from_csv("Baz quux") expect(tomato.scientific_names.size).to eq 2 end it "doesn't add a duplicate scientific name from parent" do parent = FactoryGirl.create(:crop, :name => 'parent') - parent.add_scientific_name_from_csv("Parentis cropis") + parent.add_scientific_names_from_csv("Parentis cropis") parent.save parent.reload tomato = FactoryGirl.create(:tomato, :parent => parent) expect(tomato.scientific_names.size).to eq 0 - tomato.add_scientific_name_from_csv('') + tomato.add_scientific_names_from_csv('') expect(tomato.scientific_names.size).to eq 1 # picks up parent SN - tomato.add_scientific_name_from_csv('') + tomato.add_scientific_names_from_csv('') expect(tomato.scientific_names.size).to eq 1 # shouldn't increase now end @@ -424,6 +424,33 @@ describe Crop do expect(loaded.scientific_names.last.scientific_name).to eq "Solanum lycopersicum" end + it "loads a crop with multiple scientific names" do + tomato_row = "tomato,http://en.wikipedia.org/wiki/Tomato,,\"Foo, Bar\"" + CSV.parse(tomato_row) do |row| + Crop.create_from_csv(row) + end + + loaded = Crop.last + expect(loaded.name).to eq "tomato" + expect(loaded.scientific_names.size).to eq 2 + expect(loaded.scientific_names.first.scientific_name).to eq "Foo" + expect(loaded.scientific_names.last.scientific_name).to eq "Bar" + end + + it "loads multiple scientific names with variant spacing" do + tomato_row = "tomato2,http://en.wikipedia.org/wiki/Tomato,,\"Foo,Bar\"" # no space + CSV.parse(tomato_row) do |row| + Crop.create_from_csv(row) + end + expect(Crop.last.scientific_names.size).to eq 2 + + tomato_row = "tomato3,http://en.wikipedia.org/wiki/Tomato,,\"Foo, Bar\"" # double space + CSV.parse(tomato_row) do |row| + Crop.create_from_csv(row) + end + expect(Crop.last.scientific_names.size).to eq 2 + end + it "loads a crop with a parent" do parent = FactoryGirl.create(:crop, :name => 'parent') tomato_row = "tomato,http://en.wikipedia.org/wiki/Tomato,parent" From b06d48091e0e78b7e3d9497e224acd244f23cb26 Mon Sep 17 00:00:00 2001 From: Yoong Kang Lim Date: Sun, 30 Nov 2014 15:50:13 +1100 Subject: [PATCH 29/38] Indentation problem --- spec/models/follow_spec.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/models/follow_spec.rb b/spec/models/follow_spec.rb index 3b672af34..27b42de15 100644 --- a/spec/models/follow_spec.rb +++ b/spec/models/follow_spec.rb @@ -2,10 +2,10 @@ require 'spec_helper' describe Follow do - before(:each) do - @member1 = FactoryGirl.create(:member) - @member2 = FactoryGirl.create(:member) - end + before(:each) do + @member1 = FactoryGirl.create(:member) + @member2 = FactoryGirl.create(:member) + end it "sends a notification when a follow is created" do expect { From 593a20c0c58e28f6bfc9d971c78d78dc4be0bee0 Mon Sep 17 00:00:00 2001 From: Skud Date: Sun, 30 Nov 2014 16:06:43 +1100 Subject: [PATCH 30/38] Load alternate names from CSV --- app/models/crop.rb | 29 ++++++- spec/models/crop_spec.rb | 163 +++++++++++++++++++++++++-------------- 2 files changed, 130 insertions(+), 62 deletions(-) diff --git a/app/models/crop.rb b/app/models/crop.rb index f2a182472..b63f9a8a5 100644 --- a/app/models/crop.rb +++ b/app/models/crop.rb @@ -127,7 +127,7 @@ class Crop < ActiveRecord::Base # - scientific name (optional, can be picked up from parent if it has one) def Crop.create_from_csv(row) - name,en_wikipedia_url,parent,scientific_names = row + name,en_wikipedia_url,parent,scientific_names,alternate_names = row cropbot = Member.find_by_login_name('cropbot') raise "cropbot account not found: run rake db:seed" unless cropbot @@ -148,6 +148,7 @@ class Crop < ActiveRecord::Base end crop.add_scientific_names_from_csv(scientific_names) + crop.add_alternate_names_from_csv(alternate_names) end @@ -162,12 +163,13 @@ class Crop < ActiveRecord::Base end if names_to_add.size > 0 + cropbot = Member.find_by_login_name('cropbot') + raise "cropbot account not found: run rake db:seed" unless cropbot + names_to_add.each do |n| if self.scientific_names.exists?(:scientific_name => n) logger.warn("Warning: skipping duplicate scientific name #{n} for #{self}") else - cropbot = Member.find_by_login_name('cropbot') - raise "cropbot account not found: run rake db:seed" unless cropbot self.scientific_names.create( :scientific_name => n, @@ -176,7 +178,28 @@ class Crop < ActiveRecord::Base end end end + end + def add_alternate_names_from_csv(alternate_names) + names_to_add = [] + if ! alternate_names.blank? # i.e. we actually passed something in, which isn't a given + cropbot = Member.find_by_login_name('cropbot') + raise "cropbot account not found: run rake db:seed" unless cropbot + + names_to_add = alternate_names.split(%r{,\s*}) + + names_to_add.each do |n| + if self.alternate_names.exists?(:name => n) + logger.warn("Warning: skipping duplicate alternate name #{n} for #{self}") + else + self.alternate_names.create( + :name => n, + :creator_id => cropbot.id + ) + end + end + + end end # Crop.search(string) diff --git a/spec/models/crop_spec.rb b/spec/models/crop_spec.rb index 0c41a343f..5bd7d01ba 100644 --- a/spec/models/crop_spec.rb +++ b/spec/models/crop_spec.rb @@ -351,52 +351,111 @@ describe Crop do @cropbot = FactoryGirl.create(:cropbot) end - it "adds a scientific name to a crop that has none" do - tomato = FactoryGirl.create(:tomato) - expect(tomato.scientific_names.size).to eq 0 - tomato.add_scientific_names_from_csv("Foo bar") - expect(tomato.scientific_names.size).to eq 1 - expect(tomato.default_scientific_name).to eq "Foo bar" - end + context "scientific names" do - it "picks up scientific name from parent crop if available" do - parent = FactoryGirl.create(:crop, :name => 'parent crop') - parent.add_scientific_names_from_csv("Parentis cropis") - parent.save - parent.reload + it "adds a scientific name to a crop that has none" do + tomato = FactoryGirl.create(:tomato) + expect(tomato.scientific_names.size).to eq 0 + tomato.add_scientific_names_from_csv("Foo bar") + expect(tomato.scientific_names.size).to eq 1 + expect(tomato.default_scientific_name).to eq "Foo bar" + end - tomato = FactoryGirl.create(:tomato, :parent => parent) - expect(tomato.parent).to eq parent - expect(tomato.parent.default_scientific_name).to eq "Parentis cropis" + it "picks up scientific name from parent crop if available" do + parent = FactoryGirl.create(:crop, :name => 'parent crop') + parent.add_scientific_names_from_csv("Parentis cropis") + parent.save + parent.reload - tomato.add_scientific_names_from_csv('') - expect(tomato.default_scientific_name).to eq "Parentis cropis" - end + tomato = FactoryGirl.create(:tomato, :parent => parent) + expect(tomato.parent).to eq parent + expect(tomato.parent.default_scientific_name).to eq "Parentis cropis" - it "doesn't add a duplicate scientific name" do - tomato = FactoryGirl.create(:tomato) - expect(tomato.scientific_names.size).to eq 0 - tomato.add_scientific_names_from_csv("Foo bar") - expect(tomato.scientific_names.size).to eq 1 - tomato.add_scientific_names_from_csv("Foo bar") - expect(tomato.scientific_names.size).to eq 1 # shouldn't increase - tomato.add_scientific_names_from_csv("Baz quux") - expect(tomato.scientific_names.size).to eq 2 - end + tomato.add_scientific_names_from_csv('') + expect(tomato.default_scientific_name).to eq "Parentis cropis" + end - it "doesn't add a duplicate scientific name from parent" do - parent = FactoryGirl.create(:crop, :name => 'parent') - parent.add_scientific_names_from_csv("Parentis cropis") - parent.save - parent.reload + it "doesn't add a duplicate scientific name" do + tomato = FactoryGirl.create(:tomato) + expect(tomato.scientific_names.size).to eq 0 + tomato.add_scientific_names_from_csv("Foo bar") + expect(tomato.scientific_names.size).to eq 1 + tomato.add_scientific_names_from_csv("Foo bar") + expect(tomato.scientific_names.size).to eq 1 # shouldn't increase + tomato.add_scientific_names_from_csv("Baz quux") + expect(tomato.scientific_names.size).to eq 2 + end - tomato = FactoryGirl.create(:tomato, :parent => parent) - expect(tomato.scientific_names.size).to eq 0 - tomato.add_scientific_names_from_csv('') - expect(tomato.scientific_names.size).to eq 1 # picks up parent SN - tomato.add_scientific_names_from_csv('') - expect(tomato.scientific_names.size).to eq 1 # shouldn't increase now - end + it "doesn't add a duplicate scientific name from parent" do + parent = FactoryGirl.create(:crop, :name => 'parent') + parent.add_scientific_names_from_csv("Parentis cropis") + parent.save + parent.reload + + tomato = FactoryGirl.create(:tomato, :parent => parent) + expect(tomato.scientific_names.size).to eq 0 + tomato.add_scientific_names_from_csv('') + expect(tomato.scientific_names.size).to eq 1 # picks up parent SN + tomato.add_scientific_names_from_csv('') + expect(tomato.scientific_names.size).to eq 1 # shouldn't increase now + end + + it "loads a crop with multiple scientific names" do + tomato = FactoryGirl.create(:tomato) + expect(tomato.scientific_names.size).to eq 0 + tomato.add_scientific_names_from_csv("Foo, Bar") + expect(tomato.scientific_names.size).to eq 2 + expect(tomato.scientific_names[0].scientific_name).to eq "Foo" + expect(tomato.scientific_names[1].scientific_name).to eq "Bar" + end + + it "loads multiple scientific names with variant spacing" do + tomato = FactoryGirl.create(:tomato) + expect(tomato.scientific_names.size).to eq 0 + tomato.add_scientific_names_from_csv("Foo,Bar") # no space + expect(tomato.scientific_names.size).to eq 2 + tomato.add_scientific_names_from_csv("Baz, Quux") # multiple spaces + expect(tomato.scientific_names.size).to eq 4 + end + + end # scientific names + + context "alternate names" do + it "loads an alternate name" do + tomato = FactoryGirl.create(:tomato) + expect(tomato.alternate_names.size).to eq 0 + tomato.add_alternate_names_from_csv("Foo") + expect(tomato.alternate_names.size).to eq 1 + expect(tomato.alternate_names.last.name).to eq "Foo" + end + + it "doesn't load duplicate alternate names" do + tomato = FactoryGirl.create(:tomato) + expect(tomato.alternate_names.size).to eq 0 + tomato.add_alternate_names_from_csv("Foo") + expect(tomato.alternate_names.size).to eq 1 + tomato.add_alternate_names_from_csv("Foo") + expect(tomato.alternate_names.size).to eq 1 # still 1, doesn't add another + end + + it "adds multiple alternate names" do + tomato = FactoryGirl.create(:tomato) + expect(tomato.alternate_names.size).to eq 0 + tomato.add_alternate_names_from_csv("Foo, Bar") + expect(tomato.alternate_names.size).to eq 2 + expect(tomato.alternate_names[0].name).to eq "Foo" + expect(tomato.alternate_names[1].name).to eq "Bar" + end + + it "adds multiple alt names with variant spacing" do + tomato = FactoryGirl.create(:tomato) + expect(tomato.alternate_names.size).to eq 0 + tomato.add_alternate_names_from_csv("Foo,Bar") # no space + expect(tomato.alternate_names.size).to eq 2 + tomato.add_alternate_names_from_csv("Baz, Quux") # mutliple spaces + expect(tomato.alternate_names.size).to eq 4 + end + end # alternate names it "loads the simplest possible crop" do tomato_row = "tomato,http://en.wikipedia.org/wiki/Tomato" @@ -424,31 +483,17 @@ describe Crop do expect(loaded.scientific_names.last.scientific_name).to eq "Solanum lycopersicum" end - it "loads a crop with multiple scientific names" do - tomato_row = "tomato,http://en.wikipedia.org/wiki/Tomato,,\"Foo, Bar\"" + it "loads a crop with an alternate name" do + tomato_row = "tomato,http://en.wikipedia.org/wiki/Tomato,,,Foo" + CSV.parse(tomato_row) do |row| Crop.create_from_csv(row) end loaded = Crop.last expect(loaded.name).to eq "tomato" - expect(loaded.scientific_names.size).to eq 2 - expect(loaded.scientific_names.first.scientific_name).to eq "Foo" - expect(loaded.scientific_names.last.scientific_name).to eq "Bar" - end - - it "loads multiple scientific names with variant spacing" do - tomato_row = "tomato2,http://en.wikipedia.org/wiki/Tomato,,\"Foo,Bar\"" # no space - CSV.parse(tomato_row) do |row| - Crop.create_from_csv(row) - end - expect(Crop.last.scientific_names.size).to eq 2 - - tomato_row = "tomato3,http://en.wikipedia.org/wiki/Tomato,,\"Foo, Bar\"" # double space - CSV.parse(tomato_row) do |row| - Crop.create_from_csv(row) - end - expect(Crop.last.scientific_names.size).to eq 2 + expect(loaded.alternate_names.size).to eq 1 + expect(loaded.alternate_names.last.name).to eq "Foo" end it "loads a crop with a parent" do From 82a5379a256fb5a9666211352a90e52d50b00e5d Mon Sep 17 00:00:00 2001 From: Skud Date: Mon, 1 Dec 2014 20:53:17 +1100 Subject: [PATCH 31/38] Added mint family and brassica crops (seed files) --- db/seeds/crops-12-mint.csv | 63 +++++++++++++++++++++++++++++++++ db/seeds/crops-13-brassicas.csv | 36 +++++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 db/seeds/crops-12-mint.csv create mode 100644 db/seeds/crops-13-brassicas.csv diff --git a/db/seeds/crops-12-mint.csv b/db/seeds/crops-12-mint.csv new file mode 100644 index 000000000..3da0e6fdc --- /dev/null +++ b/db/seeds/crops-12-mint.csv @@ -0,0 +1,63 @@ +salvia,http://en.wikipedia.org/wiki/Salvia,,Salvia, +white sage,http://en.wikipedia.org/wiki/Salvia_apiana,salvia,Salvia apiana,"bee sage, sacred sage" +pineapple sage,http://en.wikipedia.org/wiki/Salvia_elegans,salvia,Salvia elegans,tangerine sage +Greek sage,http://en.wikipedia.org/wiki/Salvia_fruticosa,salvia,Salvia fruticosa, +chia,http://en.wikipedia.org/wiki/Salvia_hispanica,salvia,Salvia hispanica, +baby sage,http://en.wikipedia.org/wiki/Salvia_microphylla,salvia,Salvia microphylla,"Graham's sage, Blackcurrant sage" +sage,http://en.wikipedia.org/wiki/Salvia_officinalis,salvia,Salvia officinalis,common sage +rosemary,http://en.wikipedia.org/wiki/Rosemary,,Rosemarinus officinalis, +catnip,http://en.wikipedia.org/wiki/Nepeta_cataria,,Nepeta cataria,catmint +beebalm,http://en.wikipedia.org/wiki/Monarda,,Monarda, +lemon beebalm,http://en.wikipedia.org/wiki/Monarda_citriodora,beebalm,Monarda citriodora,"purple horsemint, lemon mint" +basil beebalm,http://en.wikipedia.org/wiki/Monarda_clinopodioides,beebalm,Monarda clinopodioides, +crimson beebalm,http://en.wikipedia.org/wiki/Monarda_didyma,beebalm,Monarda didyma,"bergamot, scarlet beebalm, scarlet monarda, Oswego tea" +wild bergamot,http://en.wikipedia.org/wiki/Monarda_fistulosa,beebalm,Monarda fistulosa, +perilla,http://en.wikipedia.org/wiki/Perilla_frutescens,,Perilla frutescens, +shiso,http://en.wikipedia.org/wiki/Shiso,perilla,Perilla frutescens var. crispa, +winter savory,http://en.wikipedia.org/wiki/Winter_savory,,Satureja montana, +summer savory,http://en.wikipedia.org/wiki/Summer_savory,,Satureja hortensis, +yerba buena,http://en.wikipedia.org/wiki/Micromeria_douglasii,,Micromeria douglasii, +anise hyssop,http://en.wikipedia.org/wiki/Agastache_foeniculum,,Agastache foeniculum,"blue giant hyssop, Fragrant giant hyssop, lavender giant hyssop" +Korean mint,http://en.wikipedia.org/wiki/Agastache_rugosa,,Agastache rugosa,"Blue Licorice, Purple Giant Hyssop, Huo xiang, Indian Mint, Patchouli Herb, Wrinkled Giant Hyssop" +oregano,http://en.wikipedia.org/wiki/Oregano,,Origanum vulgare,wild marjoram +Amanum oregano,http://en.wikipedia.org/wiki/Origanum_amanum,oregano,Origanum amanum, +marjoram,http://en.wikipedia.org/wiki/Marjoram,oregano,Origanum majorana,"sweet marjoram, knotted marjoram" +Cretan oregano,http://en.wikipedia.org/wiki/Origanum_onites,oregano,Origanum onites,"Turkish oregano, pot marjoram, rίgani" +round-leafed oregano,http://en.wikipedia.org/wiki/Origanum_rotundifolium,oregano,Origanum rotundifolium, +za'atar,http://en.wikipedia.org/wiki/Origanum_syriacum,oregano,Origanum syriacum,"bible hyssop, Biblical-hyssop, Lebanese oregano, Syrian oregano" +calamint,http://en.wikipedia.org/wiki/Calamint,,Calamintha, +lesser calamint,http://en.wikipedia.org/wiki/Calamintha_nepeta,calamint,Calamintha nepeta, +thyme,http://en.wikipedia.org/wiki/Thymus_%28plant%29,,Thymus, +common thyme,http://en.wikipedia.org/wiki/Thymus_vulgaris,thyme,Thymus vulgaris,garden thyme +caraway thyme,http://en.wikipedia.org/wiki/Thymus_herba-barona,thyme,Thymus herba-barona, +cantueso,http://en.wikipedia.org/wiki/Thymus_moroderi,thyme,Thymus moroderi, +lemon thyme,http://en.wikipedia.org/wiki/Thymus_citriodorus,thyme,Thymus citriodorus,Citrus thyme +Hungarian thyme,http://en.wikipedia.org/wiki/Thymus_pannonicus,thyme,Thymus pannonicus, +creeping thyme,http://en.wikipedia.org/wiki/Thymus_praecox,thyme,Thymus praecox,Mother-of-Thyme +mint,http://en.wikipedia.org/wiki/Mentha,,Mentha, +water mint,http://en.wikipedia.org/wiki/Mentha_aquatica,mint,Mentha aquatica, +wild mint,http://en.wikipedia.org/wiki/Mentha_arvensis,mint,Mentha arvensis,"field mint, corn mint" +Asian mint,http://en.wikipedia.org/wiki/Mentha_asiatica,mint,Mentha asiatica, +Australian mint,http://en.wikipedia.org/wiki/Mentha_australis,mint,Mentha australis, +American wild mint,http://en.wikipedia.org/wiki/Mentha_canadensis,mint,Mentha candensis, +bergamot mint,http://en.wikipedia.org/wiki/Mentha_citrata,mint,Mentha citrata, +wrinkled-leaf mint,http://en.wikipedia.org/wiki/Mentha_crispata,mint,Mentha crispata, +peppermint,http://en.wikipedia.org/wiki/Peppermint,mint,Mentha piperita, +pennyroyal,http://en.wikipedia.org/wiki/Mentha_pulegium,mint,Mentha pulegium,"squaw mint, mosquito plant, pudding grass" +Corsican mint,http://en.wikipedia.org/wiki/Mentha_requienii,mint,Mentha requienii, +garden mint,http://en.wikipedia.org/wiki/Mentha_sachalinensis,mint,Mentha sachalinensis, +spearmint,http://en.wikipedia.org/wiki/Spearmint,mint,Mentha spicata, +apple mint,http://en.wikipedia.org/wiki/Mentha_suaveolens,mint,Mentha suaveolens, +lemon balm,http://en.wikipedia.org/wiki/Melissa_officinalis,,Melissa officinalis, +basil,http://en.wikipedia.org/wiki/Basil,,Ocimum basilicum, +Thai basil,http://en.wikipedia.org/wiki/Thai_basil,basil,Ocimum basilicum var. thyrsiflora, +spicy globe basil,http://en.wikipedia.org/wiki/Spicy_globe_basil,basil,Ocimum basilicum, +cinnamon basil,http://en.wikipedia.org/wiki/Cinnamon_basil,basil,Ocimum basilicum,"Vietnamese basil, Saigon basil" +dark opal basil,http://en.wikipedia.org/wiki/Dark_opal_basil,basil,Ocimum basilicum, +red rubin basil,http://en.wikipedia.org/wiki/Red_rubin_basil,basil,Ocimum basilicum, +lemon basil,http://en.wikipedia.org/wiki/Lemon_basil,basil,Ocimum × citriodorum,"Thai lemon basil, Lao basil" +holy basil,http://en.wikipedia.org/wiki/Holy_basil,,Ocimum tenuiflorum,tulasī +lavender,http://en.wikipedia.org/wiki/Lavandula,,Lavandula, +English lavender,http://en.wikipedia.org/wiki/Lavandula_angustifolia,lavender,Lavandula angustifolia,"common lavender, true lavender, narrow-leaved lavender" +French lavender,http://en.wikipedia.org/wiki/Lavandula_stoechas,lavender,Lavandula stoechas,"French lavender, Spanish lavender, topped lavender" +hyssop,http://en.wikipedia.org/wiki/Hyssop,,Hyssopus officinalis, diff --git a/db/seeds/crops-13-brassicas.csv b/db/seeds/crops-13-brassicas.csv new file mode 100644 index 000000000..9dfd355fa --- /dev/null +++ b/db/seeds/crops-13-brassicas.csv @@ -0,0 +1,36 @@ +Ethiopian mustard,https://en.wikipedia.org/wiki/Brassica_carinata,Brassica,Brassica carinata,Abyssinian mustard +elongated mustard,https://en.wikipedia.org/wiki/Brassica_elongata,Brassica,Brassica elongata, +Mediterranean cabbage,https://en.wikipedia.org/wiki/Brassica_fruticulosa,Brassica,Brassica fruticulosa,twiggy turnip +mustard greens,https://en.wikipedia.org/wiki/Brassica_juncea,Brassica,Brassica juncea,"Indian mustard, Chinese mustard, leaf mustard, kai choi" +rutabaga,https://en.wikipedia.org/wiki/Rutabaga,Brassica,"Brassica napobrassica, Brassica napus var. napobrassica","swede, Swedish turnip, turnip, yellow turnip, neep" +rapeseed,https://en.wikipedia.org/wiki/Brassica_napus,Brassica,Brassica napus," rape, oilseed rape, rapa, rappi, rapaseed, canola" +tatsoi,https://en.wikipedia.org/wiki/Brassica_narinosa,Brassica,"Brassica narinosa, Brassica rapa var. rosularis","spinach mustard, spoon mustard, Rosette bok choy" +black mustard,https://en.wikipedia.org/wiki/Brassica_nigra,Brassica,Brassica nigra, +Brassica oleracea,https://en.wikipedia.org/wiki/Brassica_oleracea,Brassica,Brassica oleracea,wild mustard +Brassica oleracea Acephela group,https://en.wikipedia.org/wiki/Acephala_group,Brassica,Brassica oleracea Acephala group, +kai lan,https://en.wikipedia.org/wiki/Kai-lan,Brassica,Brassica oleracea Alboglabra Group,"Chinese broccoli, Chinese kale, gai-lan" +Brassica rapa,https://en.wikipedia.org/wiki/Brassica_rapa,Brassica,Brassica rapa, +kohlrabi,https://en.wikipedia.org/wiki/Kohlrabi,Brassica oleracea,Brassica oleracea,"German turnip, German cabbage, turnip cabbage" +spring greens,https://en.wikipedia.org/wiki/Spring_greens,Brassica oleracea,Brassica oleracea Acephala group, +cauliflower,https://en.wikipedia.org/wiki/Cauliflower,Brassica oleracea,Brassica oleracea Botrytis group, +Romanesco broccoli,https://en.wikipedia.org/wiki/Romanesco_broccoli,Brassica oleracea,Brassica oleracea Botrytis group,"Romanesque cauliflower, Romanesco" +broccoflower,https://en.wikipedia.org/wiki/Broccoflower,Brassica oleracea,Brassica oleracea Botrytis group, +cabbage,https://en.wikipedia.org/wiki/Cabbage,Brassica oleracea,Brassica oleracea Capitata group, +red cabbage,https://en.wikipedia.org/wiki/Red_cabbage,Brassica oleracea,Brassica oleracea Capitata group,"purple cabbage, red kraut, blue kraut" +broccolini,https://en.wikipedia.org/wiki/Broccolini,Brassica oleracea,Brassica oleracea Capitata group x Alboglabra Group,"tenderstem broccoli, broccolette" +Brussels sprouts,https://en.wikipedia.org/wiki/Brussels_sprouts,Brassica oleracea,Brassica oleracea Gemmifera group, +broccoli,https://en.wikipedia.org/wiki/Broccoli,Brassica oleracea,Brassica oleracea Italica group, +Savoy cabbage,https://en.wikipedia.org/wiki/Savoy_cabbage,Brassica oleracea,Brassica oleracea var. sabauda, +January king cabbage,https://en.wikipedia.org/wiki/January_King_Cabbage,Brassica oleracea,Brassica oleracea var. sabauda, +collard greens,https://en.wikipedia.org/wiki/Collard_greens,Brassica oleracea acephela group,Brassica oleracea Acephala group,Dalmatian cabbage +kale,https://en.wikipedia.org/wiki/Kale,Brassica oleracea acephela group,Brassica oleracea Acephala group,borecole +mizuna,https://en.wikipedia.org/wiki/Mizuna,Brassica rapa,"Brassica rapa nipposinica, Brassica juncea var. japonica","shui cai, kyona, Japanese mustard, potherb mustard, Japanese greens, California peppergrass, spider mustard" +napa cabbage,https://en.wikipedia.org/wiki/Napa_cabbage,Brassica rapa,Brassica rapa subsp. pekinensis,"nappa cabbage, celery cabbage" +rapini,https://en.wikipedia.org/wiki/Rapini,Brassica rapa,"Brassica rapa subspecies rapa, Brassica rapa ruvo, Brassica rapa rapifera +","broccoli raab, broccoli rabe" +turnip,https://en.wikipedia.org/wiki/Turnip,Brassica rapa,Brassica rapa subspecies rapa,white turnip +choy sum,https://en.wikipedia.org/wiki/Choy_sum,Brassica rapa,"Brassica rapa var. parachinensis, Brassica chinensis var. parachinensis +","choi sum, Chinese flowering cabbage" +komatsuna,https://en.wikipedia.org/wiki/Komatsuna,Brassica rapa,Brassica rapa var. perviridis,Japanese mustard spinach +lacinato kale,https://en.wikipedia.org/wiki/Lacinato_kale,kale,Brassica oleracea Acephala group,"Tuscan kale, Tuscan cabbage, Italian kale, Dinosaur kale, cavolo nero, cavalo nero, black kale, flat back cabbage, palm tree kale, black Tuscan palm" +Brassica,https://en.wikipedia.org/wiki/Brassicas,,Brassica, From 30c91eb23f44213faa91ec183b86d88f329cabdf Mon Sep 17 00:00:00 2001 From: Skud Date: Mon, 1 Dec 2014 21:14:44 +1100 Subject: [PATCH 32/38] Tidy up sidebar on crop detail page --- app/views/crops/_alternate_names.html.haml | 16 +++++++ app/views/crops/_grown_for.html.haml | 8 ++-- app/views/crops/_planting_advice.html.haml | 17 ++++--- app/views/crops/_scientific_names.html.haml | 16 +++++++ app/views/crops/_varieties.html.haml | 11 +++-- app/views/crops/_wrangle.html.haml | 11 +++++ app/views/crops/show.html.haml | 48 ++++--------------- .../crops/_planting_advice.html.haml_spec.rb | 4 +- 8 files changed, 77 insertions(+), 54 deletions(-) create mode 100644 app/views/crops/_alternate_names.html.haml create mode 100644 app/views/crops/_scientific_names.html.haml create mode 100644 app/views/crops/_wrangle.html.haml diff --git a/app/views/crops/_alternate_names.html.haml b/app/views/crops/_alternate_names.html.haml new file mode 100644 index 000000000..83b595510 --- /dev/null +++ b/app/views/crops/_alternate_names.html.haml @@ -0,0 +1,16 @@ +.alternate_names + %h4 Alternate names + - if crop.alternate_names.empty? + %p None known. + - else + %ul + - crop.alternate_names.each do |an| + %li + = an.name + - if can? :edit, an + = link_to 'Edit', edit_alternate_name_path(an), { :class => 'btn btn-default btn-xs' } + - if can? :destroy, an + = link_to 'Delete', an, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs' + %p + - if can? :edit, crop + = link_to 'Add', new_alternate_name_path( :crop_id => crop.id ), { :class => 'btn btn-default btn-xs' } diff --git a/app/views/crops/_grown_for.html.haml b/app/views/crops/_grown_for.html.haml index 555371a23..e1d8544f7 100644 --- a/app/views/crops/_grown_for.html.haml +++ b/app/views/crops/_grown_for.html.haml @@ -1,5 +1,7 @@ -- if ! crop.harvests.empty? - %p - %strong Grown for: +%p + %strong Grown for: + - if crop.harvests.empty? + not known. + - else - popular_plant_parts = crop.popular_plant_parts.sort_by {|s, freq| freq }.reverse != popular_plant_parts.map {|p, freq| link_to(p, p) + " (#{freq})" }.join(", ") diff --git a/app/views/crops/_planting_advice.html.haml b/app/views/crops/_planting_advice.html.haml index bdd3ceb4d..713e6ded8 100644 --- a/app/views/crops/_planting_advice.html.haml +++ b/app/views/crops/_planting_advice.html.haml @@ -1,10 +1,15 @@ -- if crop.planted_from.length > 0 - %p - %strong Plant from: +%p + %strong Plant from: + - if crop.planted_from.empty? + not known. + - else - planted_from = crop.planted_from.sort_by {|s, freq| freq }.reverse = planted_from.map {|s, freq| "#{s} (#{freq})" }.join(", ") -- if crop.sunniness.length > 0 - %p - %strong Plant in: + +%p + %strong Plant in: + - if crop.sunniness.empty? + not known. + - else - sunniness = crop.sunniness.sort_by {|s, freq| freq }.reverse = sunniness.map {|s, freq| "#{s} (#{freq})" }.join(", ") diff --git a/app/views/crops/_scientific_names.html.haml b/app/views/crops/_scientific_names.html.haml new file mode 100644 index 000000000..ee845e543 --- /dev/null +++ b/app/views/crops/_scientific_names.html.haml @@ -0,0 +1,16 @@ +.scientific_names + %h4 Scientific names + - if crop.scientific_names.empty? + %p None known. + - else + %ul + - crop.scientific_names.each do |sn| + %li + = sn.scientific_name + - if can? :edit, sn + = link_to 'Edit', edit_scientific_name_path(sn), { :class => 'btn btn-default btn-xs' } + - if can? :destroy, sn + = link_to 'Delete', sn, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs' + %p + - if can? :edit, crop + = link_to 'Add', new_scientific_name_path( :crop_id => crop.id ), { :class => 'btn btn-default btn-xs' } diff --git a/app/views/crops/_varieties.html.haml b/app/views/crops/_varieties.html.haml index 434ea3c1f..8fec3e3a3 100644 --- a/app/views/crops/_varieties.html.haml +++ b/app/views/crops/_varieties.html.haml @@ -4,7 +4,12 @@ is a variety of = succeed "." do = link_to crop.parent, crop.parent -- if crop.varieties.count > 0 - %h3 - Varieties: + +- unless crop.varieties.empty? + %p + Varieties of #{crop.name}: + = render :partial => 'hierarchy', :locals => { :display_crops => [ crop ] } + +- if ! crop.parent and crop.varieties.empty? + %p None known. diff --git a/app/views/crops/_wrangle.html.haml b/app/views/crops/_wrangle.html.haml new file mode 100644 index 000000000..d68fadfb1 --- /dev/null +++ b/app/views/crops/_wrangle.html.haml @@ -0,0 +1,11 @@ +- if can? :edit, crop or can? :destroy, crop + %h4 Crop wrangling + %p + You are a + = succeed "." do + %strong CROP WRANGLER + %p + - if can? :edit, crop + = link_to 'Edit crop', edit_crop_path(crop), { :class => 'btn btn-default btn-xs' } + - if can? :destroy, crop + = link_to 'Delete crop', crop, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs' diff --git a/app/views/crops/show.html.haml b/app/views/crops/show.html.haml index f1518aeb2..7aae050c7 100644 --- a/app/views/crops/show.html.haml +++ b/app/views/crops/show.html.haml @@ -47,52 +47,20 @@ = will_paginate @posts, :params => {:anchor => "posts"} .col-md-3 - - if can? :edit, @crop or can? :destroy, @crop - %h4 Crop wrangling - %p - You are a - = succeed "." do - %strong CROP WRANGLER - %p - - if can? :edit, @crop - = link_to 'Edit crop', edit_crop_path(@crop), { :class => 'btn btn-default btn-xs' } - - if can? :destroy, @crop - = link_to 'Delete crop', @crop, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs' - .scientific_names - %h4 Scientific names - %ul - - @crop.scientific_names.each do |sn| - %li - = sn.scientific_name - - if can? :edit, sn - = link_to 'Edit', edit_scientific_name_path(sn), { :class => 'btn btn-default btn-xs' } - - if can? :destroy, sn - = link_to 'Delete', sn, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs' - %p - - if can? :edit, @crop - = link_to 'Add', new_scientific_name_path( :crop_id => @crop.id ), { :class => 'btn btn-default btn-xs' } + = render :partial => 'wrangle', :locals => { :crop => @crop } + = render :partial => 'scientific_names', :locals => { :crop => @crop } + = render :partial => 'alternate_names', :locals => { :crop => @crop } - .alternate_names - %h4 Alternate names - %ul - - @crop.alternate_names.each do |an| - %li - = an.name - - if can? :edit, an - = link_to 'Edit', edit_alternate_name_path(an), { :class => 'btn btn-default btn-xs' } - - if can? :destroy, an - = link_to 'Delete', an, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs' - %p - - if can? :edit, @crop - = link_to 'Add', new_alternate_name_path( :crop_id => @crop.id ), { :class => 'btn btn-default btn-xs' } - - = render :partial => 'varieties', :locals => { :crop => @crop } + %h4 Planting advice = render :partial => 'grown_for', :locals => { :crop => @crop } - = render :partial => 'planting_advice', :locals => { :crop => @crop } + %h4 Varieties + = render :partial => 'varieties', :locals => { :crop => @crop } + + %h4 More information %ul %li= link_to 'Wikipedia (English)', @crop.en_wikipedia_url diff --git a/spec/views/crops/_planting_advice.html.haml_spec.rb b/spec/views/crops/_planting_advice.html.haml_spec.rb index f92fe2bd7..19a756a7c 100644 --- a/spec/views/crops/_planting_advice.html.haml_spec.rb +++ b/spec/views/crops/_planting_advice.html.haml_spec.rb @@ -14,7 +14,7 @@ describe "crops/_planting_advice" do context "sunniness" do it "doesn't show sunniness if none are set" do render :partial => 'crops/planting_advice', :locals => { :crop => @crop } - rendered.should_not contain "Plant in:" + rendered.should contain "Plant in: not known." end it "shows sunniness frequencies" do @@ -39,7 +39,7 @@ describe "crops/_planting_advice" do it "doesn't show planted_from if none are set" do render :partial => 'crops/planting_advice', :locals => { :crop => @crop } - rendered.should_not contain "Plant from:" + rendered.should contain "Plant from: not known." end it "shows planted_from frequencies" do From d0b61c259d2f577bd34448b8e7e88eec20dc51b0 Mon Sep 17 00:00:00 2001 From: Skud Date: Mon, 1 Dec 2014 21:20:44 +1100 Subject: [PATCH 33/38] Added squashes and new crops from London working bee --- db/seeds/crops-14-london-workingbee.csv | 15 +++++++++++++++ db/seeds/crops-15-squashes.csv | 20 ++++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 db/seeds/crops-14-london-workingbee.csv create mode 100644 db/seeds/crops-15-squashes.csv diff --git a/db/seeds/crops-14-london-workingbee.csv b/db/seeds/crops-14-london-workingbee.csv new file mode 100644 index 000000000..42bddb9ec --- /dev/null +++ b/db/seeds/crops-14-london-workingbee.csv @@ -0,0 +1,15 @@ +greenstripe amaranth,https://en.wikipedia.org/wiki/Amaranthus_acanthochiton,Amaranthus,Amaranthus Acanthochiton,greenstripe +slender amaranth,https://en.wikipedia.org/wiki/Amaranthus_viridis,amaranth,Amaranthus viridis,"green amaranth, callaloo" +purple amaranth,https://en.wikipedia.org/wiki/Amaranthus_blitum,amaranth,Amaranthus blitum, +red amaranth,https://en.wikipedia.org/wiki/Amaranthus_caudatus,amaranth,Amaranthus caudatus,"blood amaranth, purple amaranth, prince's feather, Mexican grain amaranth" +red spinach,https://en.wikipedia.org/wiki/Amaranthus_dubius,amaranth,Amaranthus dubius,"Chinese spinach, spleen amaranth" +smooth amaranth,https://en.wikipedia.org/wiki/Amaranthus_hybridus,amaranth,Amaranthus hybridus,"smooth pigweed, red amaranth, slim amaranth" +Prince of Wales,https://en.wikipedia.org/wiki/Amaranthus_hypochondriacus,amaranth,Amaranthus hypochondriacus," Prince-of-Wales feather, Prince's feather" +Palmer's amaranth,https://en.wikipedia.org/wiki/Amaranthus_palmeri,amaranth,Amaranthus palmeri,"Palmer amaranth, Palmer's pigweed, carelessweed" +red-root amaranth,https://en.wikipedia.org/wiki/Amaranthus_retroflexus,amaranth,Amaranthus retroflexus,"redroot pigweed, red-rooted pigweed, common amaranth, pigweed amaranth, common tumbleweed" +spiny amaranth,https://en.wikipedia.org/wiki/Amaranthus_spinosus,amaranth,Amaranthus spinosus,"prickly amaranth, thorny amaranth" +stinging nettle,https://en.wikipedia.org/wiki/Urtica_dioica,nettle,Urtica dioica, +tree nettle,https://en.wikipedia.org/wiki/Urtica_incisa,nettle,Urtica incisa,"scrub nettle, stinging nettle" +Thunberg's amaranth,https://en.wikipedia.org/wiki/Amaranthus_thunbergii,amaranth,Amaranthus thunbergii, +tampala,https://en.wikipedia.org/wiki/Amaranthus_tricolor,amaranth,Amaranthus tricolor,"callaloo, Joseph's coat " +star anise,http://en.wikipedia.org/wiki/Illicium_verum,,Illicium verum,"star aniseed, Chinese star anise" diff --git a/db/seeds/crops-15-squashes.csv b/db/seeds/crops-15-squashes.csv new file mode 100644 index 000000000..a5f30e645 --- /dev/null +++ b/db/seeds/crops-15-squashes.csv @@ -0,0 +1,20 @@ +squash,http://en.wikipedia.org/wiki/Squash_(plant),,Cucurbita,, +Japanese pie pumpkin,http://en.wikipedia.org/wiki/Cucurbita_argyrosperma,squash,Cucurbita argyosperma,"pipian, cushaw pumpkin", +seven year melon,http://en.wikipedia.org/wiki/Cucurbita_ficifolia,squash,Cucurbita ficifolia,"Siam pumpkin, Thai marrow, thin Vermicelli pumpkin, Asian pumpkin, fig-leaf gourd, pie melon, Malabar gourd, Malabar squash, shark's-fin gourd, shark's-fin melon", +Cucurbita maxima,http://en.wikipedia.org/wiki/Cucurbita_maxima,squash,Cucurbita maxima,, +Cucurbita moschata,http://en.wikipedia.org/wiki/Cucurbita_moschata,squash,Cucurbita moschata,, +Cucurbita pepo,http://en.wikipedia.org/wiki/Cucurbita_pepo,squash,Cucurbita pepo,, +kabocha,http://en.wikipedia.org/wiki/Kabocha,Cucurbita maxima,Cucurbita maxima,"kabocha squash, Japanese pumpkin", +turban squash,http://en.wikipedia.org/wiki/Turban_squash,Cucurbita maxima,Cucurbita maxima,"Turk's turban, French turban", +red kuri squash,http://en.wikipedia.org/wiki/Red_kuri_squash,Cucurbita maxima,Cucurbita maxima,"Japanese squash, orange Hokkaido squash, baby red Hubbard squash, Uchiki kuri squash", +butternut squash,http://en.wikipedia.org/wiki/Butternut_squash,Cucurbita moschata,Cucurbita moschata,butternut pumpkin, +tromboncino,http://en.wikipedia.org/wiki/Tromboncino_(squash),Cucurbita moschata,Cucurbita moschata,zucchetta, +acorn squash,http://en.wikipedia.org/wiki/Acorn_squash,Cucurbita pepo,Cucurbita pepo var. turbinata,"pepper squash, Des Moines squash", +yellow crookneck squash,http://en.wikipedia.org/wiki/Yellow_crookneck_squash,Cucurbita pepo,Cucurbita pepo var. torticollia,, +pumpkin,http://en.wikipedia.org/wiki/Pumpkin,Cucurbita pepo,Cucurbita pepo var. pepo,,Appears no varieties have their own wikipedia pages +pattypan squash ,http://en.wikipedia.org/wiki/Pattypan_squash,Cucurbita pepo,Cucurbita pepo var. clypeata,"scallop squash, sunburst squash, granny squash, custard marrow, custard squash, cibleme, white squash, scallopini squash, schwoughksie squash", +yellow summer squash,http://en.wikipedia.org/wiki/Yellow_summer_squash,Cucurbita pepo,Cucurbita pepo var. recticollis,straightneck squash, +spaghetti squash,http://en.wikipedia.org/wiki/Spaghetti_squash,Cucurbita pepo,Cucurbita pepo var. fastigata,"vegetable spaghetti, noodle squash, vegetable marrow, spaghetti marrow, squaghetti", +zucchini,http://en.wikipedia.org/wiki/Zucchini,Cucurbita pepo,Cucurbita pepo var. cylindrica,courgette, +Delicata squash,http://en.wikipedia.org/wiki/Delicata_squash,Cucurbita pepo,Cucurbita pepo var. pepo,"peanut squash, Bohemian squash, sweet potato squash", +gem squash,http://en.wikipedia.org/wiki/Gem_squash,Cucurbita pepo,Cucurbita pepo,, From 6f3e430840b17a3fd077df572af97d4da1fb9641 Mon Sep 17 00:00:00 2001 From: Skud Date: Mon, 1 Dec 2014 21:23:15 +1100 Subject: [PATCH 34/38] Add deploy tasks for new crops --- script/deploy-tasks.sh | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/script/deploy-tasks.sh b/script/deploy-tasks.sh index 451fe0032..957ddc1b6 100755 --- a/script/deploy-tasks.sh +++ b/script/deploy-tasks.sh @@ -10,11 +10,8 @@ # echo "YYYY-MM-DD - do something or other" # rake growstuff:oneoff:something -echo "2014-09-28 - upload tomatoes" -rake growstuff:import_crops file=db/seeds/crops-11-tomatoes.csv - -echo "2014-10-02 - remove unused photos" -rake growstuff:oneoff:remove_unused_photos - -echo "2014-10-05 - generate crops_posts records for existing posts" -rake growstuff:oneoff:generate_crops_posts_records +echo "2014-12-01 - load lots of new crops" +rake growstuff:import_crops file=db/seeds/crops-12-mint.csv +rake growstuff:import_crops file=db/seeds/crops-13-brassicas.csv +rake growstuff:import_crops file=db/seeds/crops-14-london-workingbee.csv +rake growstuff:import_crops file=db/seeds/crops-15-squashes.csv From 9f54641e9585dbf54d90602de6c1d9186e34b9c5 Mon Sep 17 00:00:00 2001 From: Miles Gould Date: Mon, 1 Dec 2014 11:03:27 +0000 Subject: [PATCH 35/38] Find crops by name when loading altnames Crop IDs are not guaranteed to be the same on staging and production. --- lib/tasks/growstuff.rake | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/lib/tasks/growstuff.rake b/lib/tasks/growstuff.rake index b0f6c68cd..d78f6c66f 100644 --- a/lib/tasks/growstuff.rake +++ b/lib/tasks/growstuff.rake @@ -301,12 +301,16 @@ namespace :growstuff do if alternate_names.blank? then next end - alternate_names.split(/,\s*/).each do |an| - AlternateName.find_or_create( - name: an, - crop_id: crop_id, - creator_id: cropbot.id - ) + crop = Crop.find_by_name(crop_name) + if crop + alternate_names.split(/,\s*/).each do |an| + AlternateName.where( + name: an, + crop_id: crop.id, + ).first_or_create do |x| + x.creator = cropbot + end + end end end end From a47328eed45b748e413bfb062e77eb76e2d8fdd2 Mon Sep 17 00:00:00 2001 From: Skud Date: Wed, 3 Dec 2014 14:50:25 +1100 Subject: [PATCH 36/38] Fixed ordering and capitalisation in brassica import --- db/seeds/crops-13-brassicas.csv | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/db/seeds/crops-13-brassicas.csv b/db/seeds/crops-13-brassicas.csv index 9dfd355fa..75d04e82d 100644 --- a/db/seeds/crops-13-brassicas.csv +++ b/db/seeds/crops-13-brassicas.csv @@ -1,3 +1,4 @@ +Brassica,https://en.wikipedia.org/wiki/Brassicas,,Brassica, Ethiopian mustard,https://en.wikipedia.org/wiki/Brassica_carinata,Brassica,Brassica carinata,Abyssinian mustard elongated mustard,https://en.wikipedia.org/wiki/Brassica_elongata,Brassica,Brassica elongata, Mediterranean cabbage,https://en.wikipedia.org/wiki/Brassica_fruticulosa,Brassica,Brassica fruticulosa,twiggy turnip @@ -22,8 +23,8 @@ Brussels sprouts,https://en.wikipedia.org/wiki/Brussels_sprouts,Brassica olerace broccoli,https://en.wikipedia.org/wiki/Broccoli,Brassica oleracea,Brassica oleracea Italica group, Savoy cabbage,https://en.wikipedia.org/wiki/Savoy_cabbage,Brassica oleracea,Brassica oleracea var. sabauda, January king cabbage,https://en.wikipedia.org/wiki/January_King_Cabbage,Brassica oleracea,Brassica oleracea var. sabauda, -collard greens,https://en.wikipedia.org/wiki/Collard_greens,Brassica oleracea acephela group,Brassica oleracea Acephala group,Dalmatian cabbage -kale,https://en.wikipedia.org/wiki/Kale,Brassica oleracea acephela group,Brassica oleracea Acephala group,borecole +collard greens,https://en.wikipedia.org/wiki/Collard_greens,Brassica oleracea Acephela group,Brassica oleracea Acephala group,Dalmatian cabbage +kale,https://en.wikipedia.org/wiki/Kale,Brassica oleracea Acephela group,Brassica oleracea Acephala group,borecole mizuna,https://en.wikipedia.org/wiki/Mizuna,Brassica rapa,"Brassica rapa nipposinica, Brassica juncea var. japonica","shui cai, kyona, Japanese mustard, potherb mustard, Japanese greens, California peppergrass, spider mustard" napa cabbage,https://en.wikipedia.org/wiki/Napa_cabbage,Brassica rapa,Brassica rapa subsp. pekinensis,"nappa cabbage, celery cabbage" rapini,https://en.wikipedia.org/wiki/Rapini,Brassica rapa,"Brassica rapa subspecies rapa, Brassica rapa ruvo, Brassica rapa rapifera @@ -33,4 +34,3 @@ choy sum,https://en.wikipedia.org/wiki/Choy_sum,Brassica rapa,"Brassica rapa var ","choi sum, Chinese flowering cabbage" komatsuna,https://en.wikipedia.org/wiki/Komatsuna,Brassica rapa,Brassica rapa var. perviridis,Japanese mustard spinach lacinato kale,https://en.wikipedia.org/wiki/Lacinato_kale,kale,Brassica oleracea Acephala group,"Tuscan kale, Tuscan cabbage, Italian kale, Dinosaur kale, cavolo nero, cavalo nero, black kale, flat back cabbage, palm tree kale, black Tuscan palm" -Brassica,https://en.wikipedia.org/wiki/Brassicas,,Brassica, From c1bcbd2e7da9bc63ff10578684a2165a574161cf Mon Sep 17 00:00:00 2001 From: Skud Date: Wed, 3 Dec 2014 14:56:13 +1100 Subject: [PATCH 37/38] Fix parent crop for B. oleracea Acephela group --- db/seeds/crops-13-brassicas.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/seeds/crops-13-brassicas.csv b/db/seeds/crops-13-brassicas.csv index 75d04e82d..858538b74 100644 --- a/db/seeds/crops-13-brassicas.csv +++ b/db/seeds/crops-13-brassicas.csv @@ -8,7 +8,7 @@ rapeseed,https://en.wikipedia.org/wiki/Brassica_napus,Brassica,Brassica napus," tatsoi,https://en.wikipedia.org/wiki/Brassica_narinosa,Brassica,"Brassica narinosa, Brassica rapa var. rosularis","spinach mustard, spoon mustard, Rosette bok choy" black mustard,https://en.wikipedia.org/wiki/Brassica_nigra,Brassica,Brassica nigra, Brassica oleracea,https://en.wikipedia.org/wiki/Brassica_oleracea,Brassica,Brassica oleracea,wild mustard -Brassica oleracea Acephela group,https://en.wikipedia.org/wiki/Acephala_group,Brassica,Brassica oleracea Acephala group, +Brassica oleracea Acephela group,https://en.wikipedia.org/wiki/Acephala_group,Brassica oleracea,Brassica oleracea Acephala group, kai lan,https://en.wikipedia.org/wiki/Kai-lan,Brassica,Brassica oleracea Alboglabra Group,"Chinese broccoli, Chinese kale, gai-lan" Brassica rapa,https://en.wikipedia.org/wiki/Brassica_rapa,Brassica,Brassica rapa, kohlrabi,https://en.wikipedia.org/wiki/Kohlrabi,Brassica oleracea,Brassica oleracea,"German turnip, German cabbage, turnip cabbage" From 58728f6a611d3acc3f7bf4aad1f206c4506b3b5b Mon Sep 17 00:00:00 2001 From: emmawinston Date: Fri, 5 Dec 2014 02:45:39 +0000 Subject: [PATCH 38/38] Made crop thumbnail markup more semantic --- app/assets/stylesheets/overrides.css.less | 18 ++++++++++++++++++ app/views/crops/_thumbnail.html.haml | 4 ++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/app/assets/stylesheets/overrides.css.less b/app/assets/stylesheets/overrides.css.less index 8b9938c33..e08579efb 100644 --- a/app/assets/stylesheets/overrides.css.less +++ b/app/assets/stylesheets/overrides.css.less @@ -159,6 +159,24 @@ p.stats { .thumbnail { margin-bottom: 1.5em; + + .scientific-name small, .crop-name a { + display: inline-block; + max-width: 100%; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + line-height: 1em; + padding-bottom: 2px; + } + + .crop-name a { + padding-top: 2px; + } + + .scientific-name small { + margin-bottom: -2px; + } } li.crop-hierarchy { diff --git a/app/views/crops/_thumbnail.html.haml b/app/views/crops/_thumbnail.html.haml index b6844dabb..7ac7d786b 100644 --- a/app/views/crops/_thumbnail.html.haml +++ b/app/views/crops/_thumbnail.html.haml @@ -1,11 +1,11 @@ .thumbnail(style='height: 220px') - if crop = link_to image_tag((crop.default_photo ? crop.default_photo.thumbnail_url : 'placeholder_150.png'), :alt => crop.name, :class => 'img-rounded'), crop - %p + %p.crop-name = link_to crop.name, crop - if crop.scientific_names.count > 0 %br/ - %i + %i.scientific-name %small = crop.scientific_names.first.scientific_name %br/