Skip to content

Commit

Permalink
Merge pull request #18 from mo-nathan/naming_refactor
Browse files Browse the repository at this point in the history
Extracted NamingController from ObserverController
  • Loading branch information
mo-nathan committed Nov 15, 2014
2 parents ea00659 + 7780ff4 commit ea67b09
Show file tree
Hide file tree
Showing 33 changed files with 1,623 additions and 1,663 deletions.
98 changes: 98 additions & 0 deletions app/classes/naming_params.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# encoding: utf-8

# Encapsulates parameters needed for NamingController pages
class NamingParams
attr_accessor :naming
attr_accessor :observation
attr_accessor :vote
attr_reader :what
attr_reader :name
attr_reader :names
attr_reader :valid_names
attr_reader :reason
attr_reader :parent_deprecated
attr_reader :suggest_corrections

def initialize
@naming = Naming.new
@vote = Vote.new
@what = "" # can't be nil else rails tries to call @name.name
@reason = @naming.init_reasons
end

def resolve_name(given_name, approved_name, chosen_name)
(success, @what, @name, @names, @valid_names,
@parent_deprecated, @suggest_corrections) =
Name.resolve_name(given_name, approved_name, chosen_name)
success && @name
end

def name_missing?
if @name && @what.match(/\S/)
false
else
@naming.errors.add(:name, :validate_naming_name_missing.t)
true
end
end

def naming_is_name?
@naming.name == @name
end

def need_new_naming?
!@naming.editable? && !naming_is_name?
end

def add_reason(reason)
@reason = @naming.init_reasons(reason)
end

def name_been_proposed?
@observation.name_been_proposed?(@name)
end

def rough_draft(naming_args, vote_args,
name_str = nil, approved_name = nil, chosen_name = nil)
@naming = Naming.construct(naming_args, @observation)
@vote = Vote.construct(vote_args, @naming)
result = name_str ? resolve_name(name_str, approved_name, chosen_name) : true
@naming.name = @name
result
end

def logged_change_vote
@observation.logged_change_vote(@naming, @vote)
end

def update_name(user, reason, was_js_on)
@naming.update_name(@name, user, reason, was_js_on)
end

def change_vote(new_val)
if (new_val && (!@vote || @vote.value != new_val))
@observation.change_vote(@naming, new_val)
else
@observation.reload
@observation.calc_consensus
end
end

def save_vote
@observation.reload
@observation.change_vote(@naming, @vote.value)
@observation.log(:log_naming_created_at, name: @naming.format_name)
end

def update_naming(reason, was_js_on)
@naming.name = @name
@naming.create_reasons(reason, was_js_on)
end

def edit_init
@what = @naming.text_name
@names = nil
@valid_names = nil
@reason = @naming.init_reasons
end
end
173 changes: 28 additions & 145 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
#
# ==== Internationalization
# all_locales:: Array of available locales for which we have translations.
# translate_menu:: Translate keys in select-menu's options.
# set_locale:: (filter: determine which locale is requested)
# get_sorted_locales_from_request_header::
# (parse locale preferences from request header)
Expand All @@ -51,11 +50,8 @@
# flash_object_errors:: Add all errors for a given instance.
#
# ==== Name validation
# create_needed_names:: Creates the given name if it's been approved.
# construct_approved_names:: Creates a list of names if they've been approved.
# construct_approved_name:: (helper)
# save_names:: (helper)
# save_name:: (helper)
#
# ==== Searching
# clear_query_in_session:: Clears out Query stored in session below.
Expand Down Expand Up @@ -474,29 +470,6 @@ def all_locales
end
helper_method :all_locales

# Translate the given pulldown menu. Accepts and returns the same structure
# the select menu helper takes:
#
# <%
# menu = [
# [ :label1, value1 ],
# [ :label2, value2 ],
# ...
# ]
# select('object', 'field', translate_menu(menu), options => ...)
# %>
#
# (Just calls +l+ on each label.) (*NOTE*: this is available to views.)
#
def translate_menu(menu)
result = []
for k,v in menu
result << [ (k.is_a?(Symbol) ? k.l : k.to_s), v ]
end
return result
end
helper_method :translate_menu

# Before filter: Decide which locale to use for this request. Sets the
# Globalite default. Tries to get the locale from:
#
Expand Down Expand Up @@ -693,6 +666,7 @@ def flash_notice(*strs)
def flash_warning(*strs)
flash_notice(*strs)
session[:notice][0,1] = '1' if session[:notice][0,1] == '0'
false
end
helper_method :flash_warning

Expand All @@ -701,67 +675,44 @@ def flash_warning(*strs)
def flash_error(*strs)
flash_notice(*strs)
session[:notice][0,1] = '2' if session[:notice][0,1] != '2'
false
end
helper_method :flash_error

# Report the errors for a given ActiveRecord::Base instance. These will be
# displayed (in red) at the top of the next page the User sees.
#
# if object.save
# flash_notice "Yay!"
# else
# flash_error "Failed to save changes."
# flash_object_error(object)
# end
#
def flash_object_errors(obj)
if obj && obj.errors && (obj.errors.size > 0)
flash_error(obj.formatted_errors.join("<br/>"))
end
end

def save_with_transaction(obj)
type_sym = obj.class.to_s.underscore.to_sym
if (result = obj.save_with_transaction)
flash_notice(:runtime_created_at.t(type: type_sym))
else
flash_error(:runtime_no_save.t(type: type_sym))
flash_object_errors(obj)
end
result
end

def object_flashes(obj)
flash_object_warnings(obj)
flash_object_errors(obj)
end

def validate_object(obj)
result = obj.valid?
flash_object_errors(obj) unless result
result
end

##############################################################################
#
# :section: Name validation
#
##############################################################################

# This is called by +create_name_helper+ (used by +create_observation+,
# +create_naming+, and +edit_naming+) and +deprecate_name+. It creates a new
# name, first checking if it is a valid name, and that it has been approved
# by the user. Uses <tt>Name.find_or_create_name_and_parents(@what)</tt> to do the
# parsing.
#
# input_what:: params[:approved_name] (name that user typed before
# getting the "this name not recognized" message)
# output_what:: @what (name after "this name not recognized" message,
# must be the same or it is not "approved")
#
# Returns +nil+ if user hasn't approved the name. If approved, it creates
# and returns a new Name record (saved).
#
def create_needed_names(input_what, output_what)
result = nil
if input_what == output_what

# This returns an array of Names: genus, species, then variety (if
# applicable). New names are created for any that don't exist... but
# they need to be saved if they are new (just check if any is missing
# an id).
names = Name.find_or_create_name_and_parents(output_what)
if names.last.nil?
flash_error :runtime_no_create_name.t(:type => :name,
:value => output_what)
else
for n in names
save_name(n, :log_updated_by) if n and n.new_record?
end
end
result = names.last
end
result
end

# Goes through list of names entered by user and creates (and saves) any that
# are not in the database (but only if user has approved them).
#
Expand Down Expand Up @@ -838,7 +789,8 @@ def construct_approved_name(name_parse, approved_names, deprecate)
deprecate2 = false if name_parse.has_synonym

# Save the names (deals with deprecation here).
save_names(names, deprecate2)
Name.save_names(names, deprecate2)
names.each { |n| flash_object_errors(n) }
end
end

Expand Down Expand Up @@ -872,79 +824,10 @@ def construct_approved_name(name_parse, approved_names, deprecate)

# Deprecate and save.
synonym.change_deprecated(true)
save_name(synonym, :log_deprecated_by, :touch => true)
save_names(synonyms[0..-2], nil) # Don't change higher taxa
end
end
end

# Makes sure an array of names are saved, deprecating them if you wish.
# Inputs:
# names array of name objects (unsaved)
# deprecate create them deprecated to start with
def save_names(names, deprecate)
log = nil
unless deprecate.nil?
if deprecate
log = :log_deprecated_by
else
log = :log_approved_by
end
end
for n in names
if n and n.new_record? # Could be nil if parent is ambiguous with respect to the author
n.change_deprecated(deprecate) if deprecate
save_name(n, log)
end
end
end

# Save any changes to this name (including creating it if it is a new
# record), log the change, add the current user as the editor, and log the
# transaction appropriately for syncing with foreign databases.
def save_name(name, log=nil, args={})
log ||= :log_name_updated

# Get list of args we care about. (intersection)
changed_args = name.changed & [
:rank,
:text_name,
:author,
:citation,
:synonym,
:deprecated,
:correct_spelling,
:notes
]

# Log transaction.
xargs = { :id => name }
if name.new_record?
for arg in changed_args
xargs[arg] = name.send(arg)
end
xargs[:method] = "POST"
else
for arg in changed_args
xargs[:"set_#{arg}"] = name.send(arg)
synonym.save_with_transaction(:log_deprecated_by, :touch => true)
Name.save_names(synonyms[0..-2], nil) # Don't change higher taxa
end
xargs[:method] = "PUT"
end

# Save any changes.
if name.changed?
args = { :touch => name.altered? }.merge(args)
name.log(log, args)
if name.save
Transaction.create(xargs)
result = true
else
flash_object_errors(name)
result = false
end
end

return result
end

##############################################################################
Expand Down
4 changes: 2 additions & 2 deletions app/controllers/image_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -293,8 +293,8 @@ def cast_vote # :norobots:
##############################################################################

# Form for uploading and adding images to an observation.
# Linked from: show_observation, reuse_image, and
# create/edit_naming (via _show_images partial)
# Linked from: show_observation, reuse_image,
# naming/create, and naming/edit (via _show_images partial)
# Inputs: params[:id] (observation)
# params[:upload][:image1-4]
# params[:image][:copyright_holder]
Expand Down
Loading

0 comments on commit ea67b09

Please sign in to comment.