diff --git a/app/decorators/article_decorator.rb b/app/decorators/article_decorator.rb index 0deae62..0446f42 100644 --- a/app/decorators/article_decorator.rb +++ b/app/decorators/article_decorator.rb @@ -6,6 +6,10 @@ def author_names authors.map { |author| "#{author.full_name}" }.join(', ').html_safe end + def pages + source.first_page.to_s + source.other_pages.to_s + end + def keyword_list keywords.pluck(:name).join(', ') end @@ -13,4 +17,8 @@ def keyword_list def pdf_download_link h.link_to('Download', pdf.url) if pdf_file_name end + + def page_title + [volume.roman_numeral, pages].reject(&:blank?).join(': ') + end end diff --git a/app/models/article.rb b/app/models/article.rb index 6d22996..58acdec 100644 --- a/app/models/article.rb +++ b/app/models/article.rb @@ -10,6 +10,16 @@ class Article < ActiveRecord::Base validates :title, presence: true validates :volume, presence: true + validate :pages_format + + def pages=(pages_str) + @pages = pages_str + self.first_page, self.other_pages = split_pages(pages_str) unless pages_str.blank? + end + + def pages + [first_page.to_s, other_pages.to_s].join + end def keyword_names=(val) names = val.split(/,\s*/) @@ -19,4 +29,17 @@ def keyword_names=(val) def keyword_names keywords.pluck(:name).join(',') end + + private + + def pages_format + unless pages.blank? || @pages =~ /\A\d+\s*([-,]\s*\d+\s*)*\z/ + errors.add(:pages, 'must be a series of page numbers separated by "," or "-"') + end + end + + def split_pages(pages_str) + parts = pages_str.gsub(' ', '').split(/(-|,)/) + [parts[0], parts[1..-1].join] + end end diff --git a/db/migrate/20130902014903_create_articles.rb b/db/migrate/20130902014903_create_articles.rb index 3162676..2c26412 100644 --- a/db/migrate/20130902014903_create_articles.rb +++ b/db/migrate/20130902014903_create_articles.rb @@ -3,7 +3,8 @@ def change create_table :articles do |t| t.belongs_to :volume, index: true t.string :title - t.string :pages + t.integer :first_page + t.string :other_pages t.attachment :pdf t.timestamps diff --git a/spec/decorators/article_decorator_spec.rb b/spec/decorators/article_decorator_spec.rb new file mode 100644 index 0000000..a4ac385 --- /dev/null +++ b/spec/decorators/article_decorator_spec.rb @@ -0,0 +1,23 @@ +require 'spec_helper' + +describe ArticleDecorator do + describe '#pages' do + it 'combines the first_page and other_pages fields' do + article = FactoryGirl.build_stubbed(:article, first_page: '1', other_pages: '-20') + + expect(article.decorate.pages).to eql('1-20') + end + + it 'handles articles that only have a first_page' do + article = FactoryGirl.build_stubbed(:article, first_page: '1', other_pages: nil) + + expect(article.decorate.pages).to eql('1') + end + + it "handles articles that don't have any pages" do + article = FactoryGirl.build_stubbed(:article, first_page: nil, other_pages: nil) + + expect(article.decorate.pages).to eql('') + end + end +end diff --git a/spec/models/article_spec.rb b/spec/models/article_spec.rb index 92fe509..3dd19c8 100644 --- a/spec/models/article_spec.rb +++ b/spec/models/article_spec.rb @@ -9,4 +9,46 @@ it { should validate_presence_of(:title) } it { should validate_presence_of(:volume) } + it { should allow_value('').for(:pages) } + it { should allow_value('1').for(:pages) } + it { should allow_value('1-10').for(:pages) } + it { should allow_value('1 - 10').for(:pages) } + it { should allow_value('1,10').for(:pages) } + it { should allow_value('1, 10').for(:pages) } + it { should allow_value('1,10-20').for(:pages) } + it { should allow_value('1-10,20').for(:pages) } + it { should_not allow_value('123x').for(:pages) } + it { should_not allow_value('1-').for(:pages) } + + describe '#split_pages' do + it 'splits two numbers separated by a hyphen' do + pages_input = '1-10' + article = FactoryGirl.build(:article, pages: pages_input) + + article.save + + expect(article.first_page).to eql(1) + expect(article.other_pages).to eql('-10') + end + + it 'strips out spaces surrounding the hyphen' do + pages_input = '1 - 10' + article = FactoryGirl.build(:article, pages: pages_input) + + article.save + + expect(article.first_page).to eql(1) + expect(article.other_pages).to eql('-10') + end + + it 'splits two numbers separated by a comma' do + pages_input = '1,10' + article = FactoryGirl.build(:article, pages: pages_input) + + article.save + + expect(article.first_page).to eql(1) + expect(article.other_pages).to eql(',10') + end + end end