Skip to content

Commit

Permalink
Updates the validation behaviour on polymorphic relationships. Bibtex…
Browse files Browse the repository at this point in the history
… refactoring. Example note and identifier generation on new Bibtex records.
  • Loading branch information
mjy committed Jan 28, 2014
1 parent 8839874 commit 8d877bf
Show file tree
Hide file tree
Showing 11 changed files with 84 additions and 72 deletions.
2 changes: 1 addition & 1 deletion app/models/concerns/shared/alternate_values.rb
Expand Up @@ -2,7 +2,7 @@ module Shared::AlternateValues
extend ActiveSupport::Concern

included do
has_many :alternate_values, as: :alternate_object
has_many :alternate_values, as: :alternate_object, validate: false
end

def has_alternate_values?
Expand Down
2 changes: 1 addition & 1 deletion app/models/concerns/shared/citable.rb
Expand Up @@ -2,7 +2,7 @@ module Shared::Citable
extend ActiveSupport::Concern

included do
has_many :citations, as: :citation_object
has_many :citations, as: :citation_object, validate: false
end

def cited?
Expand Down
2 changes: 1 addition & 1 deletion app/models/concerns/shared/data_attributes.rb
Expand Up @@ -2,7 +2,7 @@ module Shared::DataAttributes
extend ActiveSupport::Concern

included do
has_many :data_attributes, as: :attribute_subject
has_many :data_attributes, as: :attribute_subject, validate: false
end

def has_data_attributes?
Expand Down
2 changes: 1 addition & 1 deletion app/models/concerns/shared/has_roles.rb
Expand Up @@ -2,7 +2,7 @@ module Shared::HasRoles

extend ActiveSupport::Concern
included do
has_many :roles, as: :role_object
has_many :roles, as: :role_object, validate: false
end

def has_roles?
Expand Down
2 changes: 1 addition & 1 deletion app/models/concerns/shared/identifiable.rb
Expand Up @@ -2,7 +2,7 @@ module Shared::Identifiable
extend ActiveSupport::Concern
included do

has_many :identifiers, as: :identified_object
has_many :identifiers, as: :identified_object, validate: false

#scope :creator_missing_first_name, -> { where(people: {first_name: nil}).joins(:creator)}
#scope :created_by, lambda {|person| where("created_by_id = ?", person) }
Expand Down
2 changes: 1 addition & 1 deletion app/models/concerns/shared/notable.rb
Expand Up @@ -2,7 +2,7 @@ module Shared::Notable
extend ActiveSupport::Concern

included do
has_many :notes, as: :note_object
has_many :notes, as: :note_object, validate: false
end

module ClassMethods
Expand Down
2 changes: 1 addition & 1 deletion app/models/concerns/shared/taggable.rb
Expand Up @@ -2,7 +2,7 @@ module Shared::Taggable
extend ActiveSupport::Concern

included do
has_many :tags, as: :tag_object
has_many :tags, as: :tag_object, validate: false
end

def tagged?
Expand Down
2 changes: 1 addition & 1 deletion app/models/note.rb
Expand Up @@ -4,6 +4,7 @@ class Note < ActiveRecord::Base

belongs_to :note_object, polymorphic: true
validates :note_object, presence: true
validates_presence_of :note_object_id
validates_presence_of :text

before_validation :not_a_housekeeping_field, :is_valid_attribute
Expand All @@ -21,6 +22,5 @@ def is_valid_attribute
errors.add(:note_object_attribute, 'not a valid attribute (column)') if
!(self.note_object.attributes.include?(self.note_object_attribute.to_s))
end

end
end
112 changes: 53 additions & 59 deletions app/models/source/bibtex.rb
Expand Up @@ -299,7 +299,7 @@ class Source::Bibtex < Source
soft_validate(:sv_has_title, set: :recommended_fields)
soft_validate(:sv_has_some_type_of_year, set: :recommended_fields)
soft_validate(:sv_is_article_missing_journal, set: :recommended_fields)
soft_validate(:sv_has_url, set: :recommended_fields) # probably should be sv_has_identifier instead of sv_has_url
# soft_validate(:sv_has_url, set: :recommended_fields) # probably should be sv_has_identifier instead of sv_has_url
soft_validate(:sv_missing_required_bibtex_fields, set: :bibtex_fields)

#endregion
Expand All @@ -318,7 +318,9 @@ class Source::Bibtex < Source
] # either year or stated_year is acceptable
#endregion

#region ruby-bibtex related
accepts_nested_attributes_for :notes

#region ruby-bibtex related

def to_bibtex # outputs BibTeX::Entry equivalent to me.
b = BibTeX::Entry.new(type: self.bibtex_type)
Expand All @@ -338,27 +340,15 @@ def valid_bibtex?
self.to_bibtex.valid?
end



def self.new_from_bibtex(bibtex_entry)
# TODO On input, convert ruby-bibtex.url to an identifier & ruby-bibtex.note to a notation
return false if !bibtex_entry.kind_of?(::BibTeX::Entry)
s = Source::Bibtex.new(
bibtex_type: bibtex_entry.type.to_s,
)
s = Source::Bibtex.new(bibtex_type: bibtex_entry.type.to_s)
bibtex_entry.fields.each do |key, value|
v = value.to_s.strip

case (key)
when :year
s[:year] = value.to_i
if !(s[:year].to_s == v) # has year suffix
s[:year_suffix] = v[4, v.length-1]
end
when :note
s[:note] = v
# an a TW note here
else
s[key] = v
end
s.send("#{key}=", v) # = v
end
s
end
Expand Down Expand Up @@ -428,14 +418,31 @@ def self.bibtex_author_to_person(bibtex_author)
#endregion ruby-bibtex related

#region getters & setters
def year=(value)
if value.class == String
value =~ /\A(\d\d\d\d)([a-zA-Z]*)\z/
write_attribute(:year, $1.to_i) if $1
write_attribute(:year_suffix, $2) if $2
write_attribute(:year, value) if self.year.blank?
else
write_attribute(:year, value)
end
end

def month=(value)
v = Utilities::Dates::SHORT_MONTH_FILTER[value]
v = v.to_s if !v.nil?
write_attribute(:month, v)
end

def month
read_attribute(:month)
def note=(value)
write_attribute(:note, value)
self.notes.build({text: value + " [Created on import from BibTeX.]"} ) if self.new_record?
end

def isbn=(value)
write_attribute(:isbn, value)
self.identifiers.build(type: 'Identifier::Guid::Isbn', identifier: value)
end

#endregion getters & setters
Expand All @@ -462,20 +469,10 @@ def has_writer? # contains either an author or editor
end

def has_some_year? # is there a year or stated year?
return true if !(self.year.blank?)
return true if !(self.stated_year.blank?)
return false
end

#TODO write has_note?
def has_notes?
return true if !(self.note.blank?)
# return true if Notes.has_notations?(self.id)
return false
return true if !(self.year.blank?) || !(self.stated_year.blank?)
false
end

#TODO write has_identifiers?

#endregion has_<attribute>? section

#region time/date related
Expand All @@ -492,13 +489,14 @@ def set_nomenclature_date
self.nomenclature_date = self.generate_nomenclature_date
end

# TODO: Abstract to a Date/Time module
# @return[Time] a UTC time (Uses Time instead of Date so that it can be saved as a UTC object -
# see http://www.ruby-doc.org/core-2.0.0/Time.html)
# returns nomenclature_date based on computation of the values of :year, :month, :day.
# Should only ever be called after validation!
# If :year is empty, return nil
# If :month is empty, returns 12/31/:year
# IF :day is empty, returns the last day of the month
# if :year is empty, return nil
# if :month is empty, returns 12/31/:year
# if :day is empty, returns the last day of the month
def generate_nomenclature_date
if self.year.nil?
nil
Expand All @@ -518,8 +516,6 @@ def generate_nomenclature_date

#endregion time/date related

#TODO add notes method which returns an array of all associated notes.

protected

#region hard validations
Expand Down Expand Up @@ -641,26 +637,26 @@ def sv_has_institution
end
end

def sv_has_identifier
# TODO write linkage to identifiers (rather than local field save)
# we have URL, ISBN, ISSN & LCCN as bibtex fields, but they are also identifiers.
# do need to make the linkages to identifiers as well as save in the local field?
end

def sv_has_url
# TODO need to be converted to check for a URL identifier
#if (self.URL.blank?)
# soft_validations.add(:URL, 'There is no URL associated with this source.')
#end
end

def sv_has_note
# TODO we may need to check of a note in the TW sense as well - has_note? above.
if (self.note.blank?)
soft_validations.add(:note, 'There is no note associated with this source.')
end

end
# BETH: I don't think we need these, let's discuss (Matt)
# def sv_has_identifier
# # TODO write linkage to identifiers (rather than local field save)
# # we have URL, ISBN, ISSN & LCCN as bibtex fields, but they are also identifiers.
# # do need to make the linkages to identifiers as well as save in the local field?
# end
#
# def sv_has_url
# # TODO need to be converted to check for a URL identifier
# #if (self.URL.blank?)
# # soft_validations.add(:URL, 'There is no URL associated with this source.')
# #end
# end
#
# def sv_has_note
# # TODO we may need to check of a note in the TW sense as well - has_note? above.
# if (self.note.blank?)
# soft_validations.add(:note, 'There is no note associated with this source.')
# end
# end

def sv_missing_required_bibtex_fields
case self.bibtex_type
Expand Down Expand Up @@ -723,9 +719,7 @@ def sv_missing_required_bibtex_fields
sv_has_authors
sv_has_title
sv_has_note

end

end

#endregion Soft_validation_methods
Expand Down
3 changes: 1 addition & 2 deletions lib/housekeeping/projects.rb
Expand Up @@ -4,7 +4,7 @@ module Housekeeping::Projects
extend ActiveSupport::Concern

included do
# not added tot he model, just used to extend models here
# not added to the model, just used to extend models here
related_instances = self.name.demodulize.underscore.pluralize.to_sym # if 'One::Two::Three' gives :threes
related_class = self.name

Expand All @@ -20,7 +20,6 @@ module Housekeeping::Projects
# Also extend the project
Project.class_eval do
raise 'Class name collision for Project#has_many' if self.methods and self.methods.include?(:related_instances)
# puts related_instances.to_s + " " + related_class.to_s
has_many related_instances, class_name: related_class # inverse_of: :project,
end
end
Expand Down
25 changes: 22 additions & 3 deletions spec/models/source/bibtex_spec.rb
Expand Up @@ -104,7 +104,6 @@
end
end


context 'Ruby BibTeX related instance methods' do
before(:each) do
@s = Source::Bibtex.new_from_bibtex(@gem_bibtex_entry1)
Expand All @@ -119,8 +118,28 @@
expect(@s.valid_bibtex?).to be_false
end

pending 'test conversion of BibTeX::Entry with note to Source::Bibtex'
pending 'test conversion of BibTeX::Entry identifiers (URL, ISBN, etc) to Source::Bibtex with identifiers'
specify 'with a note in a BibTeX::Entry, convert it to a Source::Bibtex with an attached Note' do
note = "This is a note.\n With multiple lines."
@valid_gem_bibtex_book.note = note
s = Source::Bibtex.new_from_bibtex(@valid_gem_bibtex_book)
expect(s.notes).to have(1).things
expect(s.notes.first.text).to eq(note + " [Created on import from BibTeX.]")
expect(s.save).to be_true
expect(s.notes.first.id.nil?).to be_false
end

specify 'with an isbn in a BibTeX::Entry, convert it to an Identifier' do
identifier = "1-84356-028-3" # TODO: update when validation on isbn happens
@valid_gem_bibtex_book.isbn = identifier
s = Source::Bibtex.new_from_bibtex(@valid_gem_bibtex_book)
expect(s.identifiers).to have(1).things
expect(s.identifiers.first.identifier).to eq(identifier)
expect(s.save).to be_true
expect(s.identifiers.first.id.nil?).to be_false
end

pending 'with an issn in a BibTeX::Entry, convert it to an Identifier'
pending 'with a doi in a BibTeX::Entry, convert it to an Identifier'
end

context 'validation' do
Expand Down

0 comments on commit 8d877bf

Please sign in to comment.