Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions app/classes/importers/forest_plots_importer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,13 @@ def read_row(values, logger)

sub_plot = @sub_plots_cache[sub_plot_code]

puts "sub_plot_code in forest_place is #{sub_plot}"

if sub_plot.nil?
# Sub-plots have other columns which are not being imported here
# type, area and all that lot.
sub_plot = find_or_create(SubPlot, :plot_id => plot.id, :sub_plot_code => sub_plot_code)
attempt_to_overwrite!(sub_plot)
@sub_plots_cache[sub_plot_code] = sub_plot
end

Expand Down
14 changes: 12 additions & 2 deletions app/classes/importers/row_importer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,17 +60,27 @@ def save_with_status!
end

def find_or_new(ar_class = nil, unique_identifiers)
batch_id = use_batch_if_it_exists(unique_identifiers)
ar_class ||= self.class.ar_class
ar_class.batch_find_or_initialize_by(@batch_id, unique_identifiers)
ar_class.batch_find_or_initialize_by(batch_id, unique_identifiers)
end

def find_or_create(ar_class = nil, unique_identifiers)
ar_class ||= self.class.ar_class
ar_class.batch_find_or_create_by!(@batch_id, unique_identifiers)
end

def use_batch_if_it_exists(unique_identifiers)
batch_id = unique_identifiers[:sub_plot][:batch_id] || unique_identifiers[:plot][:batch_id]
if batch_id
batch_id
else
@batch_id
end
end

def attempt_to_overwrite!(object)
unless object.can_overwrite(@batch_id, @overwrite_batch_id)
unless object.can_overwrite(object.batch_id, @overwrite_batch_id)
raise Gemdata::NoPermissionToOverwrite, "No permission to override #{object.class.name} from a different batch: #{object.to_json}"
end
end
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/batches_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,6 @@ def set_batch

# Never trust parameters from the scary internet, only allow the white list through.
def batch_params
params.require(:batch).permit(:import_address, :started, :finished, :transaction_passed)
params.require(:batch).permit(:import_address, :started, :finished, :transaction_passed, :duplicate)
end
end
20 changes: 19 additions & 1 deletion app/models/concerns/batch_import.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,27 @@ def batch_find_or_initialize_by(batch_id, params)

def batch_find_or_create_by!(batch_id, params)
self.find_or_create_by!(params) do |new_object|
update_batch_as_duplicate(batch_id, params)
new_object.batch_id = batch_id
end
end
end

def update_batch_as_duplicate(batch_id, params)
updated_object = use_batch_from_association(params)
if updated_object.try(:batch_id).present? && updated_object.try(:batch_id) != batch_id
batch_object = Batch.find(batch_id)
batch_object.update(duplicate: true) if batch_object.duplicate == false
end
end

def use_batch_from_association(params)
if params[:plot_code].present? && params[:fp_id].present?
Plot.where(params).first
elsif params[:tree].present?
params[:tree]
end
end

end

end
5 changes: 5 additions & 0 deletions db/migrate/20160705085200_add_duplicate_to_batches.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddDuplicateToBatches < ActiveRecord::Migration
def change
add_column :batches, :duplicate, :boolean, default: false
end
end
2 changes: 1 addition & 1 deletion db/misc_sql/delete_fp_import.sql
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ WHERE t.sub_plot_id = sp.id
AND sp.plot_id = p.id
AND p.plot_code = 'INSERT_PLOTCODE_HERE';

COMMIT;
COMMIT;
3 changes: 2 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 20160319145213) do
ActiveRecord::Schema.define(version: 20160705085200) do

# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
Expand All @@ -23,6 +23,7 @@
t.boolean "transaction_passed"
t.datetime "created_at"
t.datetime "updated_at"
t.boolean "duplicate", default: false
end

create_table "branch_architectures", force: true do |t|
Expand Down
62 changes: 44 additions & 18 deletions spec/classes/importers/forest_plots_importer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
end

it 'can read CSV' do

importer = ForestPlotsImporter.new(1, 2)
status = importer.read_row(@values, logger)
expect(status).to eq(Lookup::ImportStatus.inserted)
Expand All @@ -25,7 +24,7 @@

plot = Plot.find(tree.sub_plot.plot_id)
expect(plot.fp_id).to eq(90)
expect(plot.plot_code).to eq('TAM04')
expect(plot.plot_code).to eq('TAM-04')
expect(plot.plot_desc).to eq('Tambopata plot two swamp edge clay')

species = tree.fp_species
Expand All @@ -52,49 +51,42 @@
end

it 'selects existing plots and subplots' do

plot = Plot.create!(:plot_code => 'TAM04', :fp_id => 90, batch_id: 1)
subplot = SubPlot.create!(:plot => plot, :sub_plot_code => '1', batch_id: 1)
plot = Plot.find_or_create_by(:plot_code => 'TAM-04', :fp_id => 90, batch_id: 1)
subplot = SubPlot.find_or_create_by!(:plot => plot, :sub_plot_code => '1', batch_id: 1)

importer = ForestPlotsImporter.new(1, 1)
importer.read_row(@values, logger)
expect(importer.object.reload.sub_plot.plot).to eq(plot)
expect(importer.object.reload.sub_plot).to eq(subplot)

end

it 'selects existing species complex' do

fp_family = FpFamily.create!(apg_id: 377, name: 'Sapotaceae', batch: Batch.new)
fp_genus = FpGenus.create!(fp_id: 24801, name: 'Pouteria', fp_family: fp_family, batch: Batch.new)
fp_species = FpSpecies.create!(fp_id: 653110, name: 'Pouteria indet', fp_genus: fp_genus, batch: Batch.new)
fp_family = FpFamily.find_or_create_by!(apg_id: 377, name: 'Sapotaceae', batch_id: 1)
fp_genus = FpGenus.create!(fp_id: 24801, name: 'Pouteria', fp_family: fp_family, batch_id: 1)
fp_species = FpSpecies.create!(fp_id: 653110, name: 'Pouteria indet', fp_genus: fp_genus, batch_id: 1)

importer = ForestPlotsImporter.new(1, 2)
importer.read_row(@values, logger)
expect(importer.object.reload.fp_species).to eq(fp_species)

end

it 'creates selects an existing census' do

plot = Plot.create!(:plot_code => 'TAM04', :fp_id => 90, batch_id: 1)
sub_plot = SubPlot.create!(:plot_id => plot.id, :sub_plot_code => '1', batch_id: 1)
plot = Plot.find_or_create_by(:plot_code => 'TAM-04', :fp_id => 90, batch_id: 1)
sub_plot = SubPlot.find_or_create_by!(:plot_id => plot.id, :sub_plot_code => '1', batch_id: 1)
fp_species = FpSpecies.new
tree = Tree.create!(:tree_code => 'T2', :sub_plot => sub_plot, :fp_species => fp_species, :fp_id => 54832, batch_id: 1)
census = Census.create!(number: 1, mean_date: '1983.67', plot: plot, batch_id: 1)

importer = ForestPlotsImporter.new(1, 1)
importer.read_row(@values, logger)
expect(importer.object.reload.censuses).to include(census)

end

it 'should not incorrectly flag duplicates' do

first_importer = ForestPlotsImporter.new(1, 2)
first_status = first_importer.read_row(@values, logger)

second_values = CSV.parse_line '90,TAM-04,Tambopata plot two swamp edge clay,PERU,Oliver Phillips,1990.755,3,90,Main Plot View,,54832,377,Sapotaceae,24801,Pouteria,653110,Pouteria indet,,,2,121,121,121,121,1300,a,1,5,0,,,'
second_values = CSV.parse_line '90,TAM-04,Tambopata plot two swamp edge clay,PERU,Oliver Phillips,1990.755,3,90,Main Plot View,1,54832,377,Sapotaceae,24801,Pouteria,653110,Pouteria indet,,,2,121,121,121,121,1300,a,1,5,0,,,'
second_importer = ForestPlotsImporter.new(1, 1)
second_status = second_importer.read_row(second_values, logger)
expect(second_status).to eq(Lookup::ImportStatus.skipped)
Expand All @@ -106,7 +98,7 @@
first_importer = ForestPlotsImporter.new(1, 2)
first_status = first_importer.read_row(@values, logger)

second_values = CSV.parse_line '90,TAM-04,Tambopata plot two swamp edge clay,PERU,Oliver Phillips,1983.67,1,90,Main Plot View,,12345,377,Sapotaceae,24801,Pouteria,653110,Pouteria indet,,,2,105,105,105,105,1300,a,1,5,0,,,'
second_values = CSV.parse_line '90,TAM-04,Tambopata plot two swamp edge clay,PERU,Oliver Phillips,1983.67,1,90,Main Plot View,1,12345,377,Sapotaceae,24801,Pouteria,653110,Pouteria indet,,,2,105,105,105,105,1300,a,1,5,0,,,'
second_importer = ForestPlotsImporter.new(1, 2)
second_status = second_importer.read_row(second_values, logger)
expect(second_status).to eq(Lookup::ImportStatus.inserted)
Expand All @@ -115,6 +107,40 @@
expect(second_importer.object.reload).to_not eq(first_importer.object.reload)
end

it 'should be able to delete forest_import record using sql' do
batch = Batch.find_or_create_by!(id:2)
importer = ForestPlotsImporter.new(batch.id, 1)
status = importer.read_row(@values, logger)
tree = importer.object.reload

custom_sql = "
DELETE from dbh_measurements d USING trees t, sub_plots sp, plots p
WHERE d.tree_id = #{tree.id}
AND t.sub_plot_id = #{tree.sub_plot_id}
AND sp.plot_id = #{tree.sub_plot.plot_id}
AND p.plot_code = 'TAM-04';

DELETE from trees t USING sub_plots sp, plots p
WHERE t.sub_plot_id = #{tree.sub_plot_id}
AND sp.plot_id = #{tree.sub_plot.plot_id}
AND p.plot_code = 'TAM-04';
COMMIT;
"

ActiveRecord::Base.connection.execute(custom_sql)
expect(status).to eq(Lookup::ImportStatus.inserted)
expect{Tree.find(tree.id)}.to raise_exception(ActiveRecord::RecordNotFound)
end

it 'should be able to save forest_import record after an sql delete' do
batch = Batch.find_or_create_by!(id:2)
importer = ForestPlotsImporter.new(batch.id, 1)
status = importer.read_row(@values, logger)
tree = importer.object.reload
tree_from_db = Tree.find(tree.id)
expect(tree_from_db.id).to eq(tree.id)
end

it 'should trim imports damn it!'


Expand Down
8 changes: 8 additions & 0 deletions spec/support/database_cleaner.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
require "rake"

RSpec.configure do |config|
config.after :all do
Gemdata::Application.load_tasks
Rake::Task['db:reset'].invoke
end
end