1class DebateOutcome < ActiveRecord::Base
 
2  # By default we want the user to upload a '2x' style image, and we can then
 
3  # resize it down with Imagemagick
 
4  COMMONS_IMAGE_SIZE = { w: 1260.0, h: 710.0 }
 
5
 
6  belongs_to :petition, touch: true
 
7
 
8  validates :petition, presence: true
 
 9  validates :debated_on, presence: true, if: :debated?
 
10  validates :transcript_url, :video_url, :debate_pack_url, length: { maximum: 500 }
 
 
12  has_attached_file :commons_image,
 
13    # default_url needs to be a lambda - this way the generated image url will
 
14    # include any asset-digest
 
15    default_url: ->(_) { ActionController::Base.helpers.image_url("graphics/graphic_house-of-commons.jpg") },
 
16    styles: {
 
17      "1x": "#{(COMMONS_IMAGE_SIZE[:w]/2).to_i}x#{(COMMONS_IMAGE_SIZE[:h]/2).to_i}",
 
18      "2x": "#{COMMONS_IMAGE_SIZE[:w]}x#{COMMONS_IMAGE_SIZE[:h]}"
 
19    }
 
 
21  validates_attachment_content_type :commons_image, content_type: /\Aimage\/.*\Z/
 
22  validate :validate_commons_image_dimensions, unless: :no_commons_image_queued
 
 
24  after_create do
 
25    petition.touch(:debate_outcome_at) unless petition.debate_outcome_at?
 
26  end
 
 
28  after_save do
 
29    petition.update_columns(debate_state: debate_state)
 
30  end
 
  • Complexity 1 » saikuro
32  def date
 
33    debated_on
 
34  end
 
 
36  private
 
  • Complexity 2 » saikuro
38  def debate_state
 
39    debated? ? 'debated' : 'not_debated'
 
40  end
 
  • UtilityFunction - doesn't depend on instance state (maybe move it to another class?) » reek
  • Complexity 1 » saikuro
42  def image_ratio(width, height)
 
43    (width.to_f / height.to_f).round(2)
 
44  end
 
  • Complexity 1 » saikuro
46  def no_commons_image_queued
 
47    commons_image.blank? || !commons_image.queued_for_write[:original]
 
48  end
 
  • DuplicateMethodCall - calls 'COMMONS_IMAGE_SIZE[:h]' 3 times » reek
  • DuplicateMethodCall - calls 'COMMONS_IMAGE_SIZE[:w]' 3 times » reek
  • DuplicateMethodCall - calls 'dimensions.height' 3 times » reek
  • DuplicateMethodCall - calls 'dimensions.width' 3 times » reek
  • TooManyStatements - has approx 9 statements » reek
  • Complexity 4 » saikuro
50  def validate_commons_image_dimensions
 
51    # This should be tuned if the images start looking badly scaled
 
52    max_ratio_delta = 0.1
 
 
54    dimensions = Paperclip::Geometry.from_file(commons_image.queued_for_write[:original].path)
 
 
56    if dimensions.width < COMMONS_IMAGE_SIZE[:w]
 
57      errors.add(:commons_image, :too_narrow, width: dimensions.width, min_width: COMMONS_IMAGE_SIZE[:w])
 
58    end
 
 
60    if dimensions.height < COMMONS_IMAGE_SIZE[:h]
 
61      errors.add(:commons_image, :too_short, height: dimensions.height, min_height: COMMONS_IMAGE_SIZE[:h])
 
62    end
 
 
64    expected_ratio = image_ratio(COMMONS_IMAGE_SIZE[:w], COMMONS_IMAGE_SIZE[:h])
 
65    actual_ratio = image_ratio(dimensions.width, dimensions.height)
 
 
67    min_ratio = (expected_ratio - max_ratio_delta).round(2)
 
68    max_ratio = (expected_ratio + max_ratio_delta).round(2)
 
69    unless (min_ratio..max_ratio).include? actual_ratio
 
70      errors.add(:commons_image, :incorrect_ratio, ratio: actual_ratio, min_ratio: min_ratio, max_ratio: max_ratio)
 
71    end
 
72  end
 
73end