This commit is contained in:
Bertocq
2017-06-27 17:57:35 +02:00
committed by Senén Rodero Rodríguez
parent 886431b43d
commit 614ff79ba1
15 changed files with 135 additions and 68 deletions

View File

@@ -93,9 +93,7 @@ module Budgets
end end
def remove_image def remove_image
@investment.image.destroy @investment.image.destroy!
@investment.image_title = nil
@investment.save
redirect_to budget_investment_path(@investment.budget, @investment), redirect_to budget_investment_path(@investment.budget, @investment),
notice: t("flash.actions.remove_image.budget_investment") notice: t("flash.actions.remove_image.budget_investment")
end end
@@ -128,7 +126,7 @@ module Budgets
params.require(:budget_investment) params.require(:budget_investment)
.permit(:title, :description, :external_url, :heading_id, .permit(:title, :description, :external_url, :heading_id,
:tag_list, :organization_name, :location, :terms_of_service, :tag_list, :organization_name, :location, :terms_of_service,
:image, :image_title, image_attributes: [:title, :attachment],
documents_attributes: [:id, :title, :attachment, :cached_attachment, :user_id]) documents_attributes: [:id, :title, :attachment, :cached_attachment, :user_id])
end end

View File

@@ -1,32 +1,23 @@
module InvestmentsHelper module InvestmentsHelper
def investment_image_full_url(investment, version) def investment_image_full_url(investment, version)
URI(request.url) + investment.image.url(version) URI(request.url) + investment.image_url(version)
end
def investment_image_file_name(investment)
investment.image.url.split('/').last.split("?")[0] if investment.image.present?
end end
def investment_image_advice_note(investment) def investment_image_advice_note(investment)
title = investment.title
if investment.image.exists? if investment.image.exists?
t "budgets.investments.edit_image.edit_note", title: title t("budgets.investments.edit_image.edit_note", title: investment.title)
else else
t "budgets.investments.edit_image.add_note", title: title t("budgets.investments.edit_image.add_note", title: investment.title)
end end
end end
def investment_image_button_text(investment) def investment_image_button_text(investment)
if investment.image.exists? investment.image.exists? ? t("budgets.investments.show.edit_image") : t("budgets.investments.show.add_image")
t "budgets.investments.show.edit_image"
else
t "budgets.investments.show.add_image"
end
end end
def errors_on_image(investment) def errors_on_image(investment)
investment.errors[:image].join(', ') if investment.errors.key?(:image) investment.errors[:attachment].join(', ') if investment.errors.key?(:attachment)
end end
end end

View File

@@ -8,6 +8,7 @@ class Budget
include Followable include Followable
include Communitable include Communitable
include Documentable include Documentable
include Imageable
documentable max_documents_allowed: 3, documentable max_documents_allowed: 3,
max_file_size: 3.megabytes, max_file_size: 3.megabytes,
accepted_content_types: [ "application/pdf" ] accepted_content_types: [ "application/pdf" ]
@@ -17,7 +18,6 @@ class Budget
acts_as_paranoid column: :hidden_at acts_as_paranoid column: :hidden_at
include ActsAsParanoidAliases include ActsAsParanoidAliases
belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id' belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id'
belongs_to :heading belongs_to :heading
belongs_to :group belongs_to :group

View File

@@ -0,0 +1,14 @@
# can [:update, :destroy ], Image, :imageable_id => user.id, :imageable_type => 'User'
# and add a feature like forbidden/without_role_images_spec.rb to test it
module Imageable
extend ActiveSupport::Concern
included do
has_one :image, as: :imageable, dependent: :destroy
accepts_nested_attributes_for :image, allow_destroy: true
def image_url(style)
image.attachment.url(style) if image && image.attachment.exists?
end
end
end

48
app/models/image.rb Normal file
View File

@@ -0,0 +1,48 @@
class Image < ActiveRecord::Base
TITLE_LEGHT_RANGE = 4..80
MIN_SIZE = 475
attr_accessor :content_type, :original_filename, :attachment_data, :attachment_urls
belongs_to :imageable, polymorphic: true
before_validation :set_styles
has_attached_file :attachment, styles: { large: "x475", medium: "300x300#", thumb: "140x245#" },
url: "/system/:class/:attachment/:imageable_name_path/:style/:hash.:extension",
hash_secret: Rails.application.secrets.secret_key_base
validates_attachment :attachment, presence: true, content_type: { content_type: %w(image/jpeg image/jpg) },
size: { less_than: 1.megabytes }
validates :title, presence: true, length: { in: TITLE_LEGHT_RANGE }
validate :check_image_dimensions
after_create :redimension_using_origin_styles
accepts_nested_attributes_for :imageable
# # overwrite default styles for Image class
# def set_image_styles
# { large: "x#{MIN_SIZE}", medium: "300x300#", thumb: "140x245#" }
# end
def set_styles
if imageable
imageable.set_styles if imageable.respond_to? :set_styles
else
{ large: "x#{MIN_SIZE}", medium: "300x300#", thumb: "140x245#" }
end
end
Paperclip.interpolates :imageable_name_path do |attachment, _style|
attachment.instance.imageable.class.to_s.downcase.split('::').map(&:pluralize).join('/')
end
private
def redimension_using_origin_styles
attachment.reprocess!
end
def check_image_dimensions
return unless attachment?
dimensions = Paperclip::Geometry.from_file(attachment.queued_for_write[:original].path)
errors.add(:attachment, :min_image_width, required_min_width: MIN_SIZE) if dimensions.width < MIN_SIZE
errors.add(:attachment, :min_image_height, required_min_height: MIN_SIZE) if dimensions.height < MIN_SIZE
end
end

View File

@@ -53,26 +53,28 @@
data: {js_url: suggest_tags_path} %> data: {js_url: suggest_tags_path} %>
</div> </div>
<div class="small-12 column"> <%= f.fields_for :image do |builder| %>
<div class="image-upload">
<%= f.file_field :image, accept: 'image/jpeg', label: false, class:'show-for-sr' %>
<br>
<%= f.label :image, t("budgets.investments.form.image_label"), class:'button' %>
<p><%= investment_image_file_name(@investment) %></p>
</div>
</div>
<% if @investment.errors.has_key?(:image) %>
<div class="small-12 column"> <div class="small-12 column">
<div class="image-errors"> <div class="image-upload">
<small class="error"><%= errors_on_image(@investment)%></small> <%= f.file_field :attachment, accept: 'image/jpg,image/jpeg', label: false, class:'show-for-sr' %>
<br>
<%= f.label :attachment, t("budgets.investments.form.image_label"), class:'button' %>
</div> </div>
</div> </div>
<% end %>
<div class="small-12 column"> <% if @investment.errors.has_key?(:attachment) %>
<%= f.text_field :image_title %> <div class="small-12 column">
</div> <div class="image-errors">
<small class="error"><%= errors_on_image(@investment)%></small>
</div>
</div>
<% end %>
<div class="small-12 column">
<%= f.text_field :title %>
</div>
<% end %>
<% unless current_user.manager? %> <% unless current_user.manager? %>

View File

@@ -10,16 +10,15 @@
<% if @investment.image.exists? %> <% if @investment.image.exists? %>
<div class="small-12 column"> <div class="small-12 column">
<%= image_tag @investment.image.url(:large) %> <%= image_tag @investment.image_url(:large) %>
</div> </div>
<% end %> <% end %>
<div class="small-12 column"> <div class="small-12 column">
<div class="image-upload"> <div class="image-upload">
<%= f.file_field :image, accept: 'image/jpeg', label: false, class:'show-for-sr' %> <%= f.file_field :attachment, accept: 'image/jpg,image/jpeg', label: false, class:'show-for-sr' %>
<br> <br>
<%= f.label :image, t("budgets.investments.edit_image.form.image_label"), class:'button' %> <%= f.label :attachment, t("budgets.investments.edit_image.form.image_label"), class:'button' %>
<p><%= investment_image_file_name(@investment) %></p>
</div> </div>
</div> </div>
@@ -32,18 +31,21 @@
<% end %> <% end %>
<div class="small-12 column"> <div class="small-12 column">
<%= f.label :image_title, t("budgets.investments.edit_image.form.image_title") %> <%= f.label :title, t("budgets.investments.edit_image.form.image_title") %>
<%= f.text_field :image_title, placeholder: t("budgets.investments.edit_image.form.image_title"), label: false %> <%= f.text_field :title, placeholder: t("budgets.investments.edit_image.form.image_title"), label: false %>
</div> </div>
<div class="actions small-12 column"> <div class="actions small-12 column">
<%= f.submit(class: "button", value: t("budgets.investments.edit_image.form.submit_button")) %> <%= f.submit(class: "button", value: t("budgets.investments.edit_image.form.submit_button")) %>
<% if @investment.image.exists? %> <% if @investment.image.exists? %>
<%= link_to t("budgets.investments.edit_image.form.remove_button"), <div class="float-right">
remove_image_budget_investment_path(@investment.budget, @investment), <%= link_to t("budgets.investments.edit_image.form.remove_button"),
class: "button hollow alert", remove_image_budget_investment_path(@investment.budget, @investment),
method: :delete, class: "button hollow alert",
data: { confirm: t("budgets.investments.edit_image.form.remove_alert") } %> method: :delete,
data: { confirm: t("budgets.investments.edit_image.form.remove_alert") } %>
</div>
<% end %> <% end %>
</div> </div>

View File

@@ -4,15 +4,10 @@
<div class="small-12 medium-3 large-2 column"> <div class="small-12 medium-3 large-2 column">
<% if investment.image.exists? %> <% if investment.image.exists? %>
<picture> <figure>
<source srcset="<%= investment.image.url(:medium) %>" <%= image_tag investment.image_url(:thumb), alt: investment.image.title %>
alt="<%= investment.image_title %>" <figcaption><%= investment.image.title %></figcaption>
title= "<%= investment.image_title %>" </figure>
media="(max-width: 640px)">
<img srcset="<%= investment.image.url(:thumb) %>"
alt="<%= investment.image_title %>"
title="<%= investment.image_title %>">
</picture>
<% else %> <% else %>
<div class="no-image"></div> <div class="no-image"></div>
<% end %> <% end %>

View File

@@ -32,11 +32,10 @@
<div class="row"> <div class="row">
<div class="small-12 column text-center"> <div class="small-12 column text-center">
<figure> <figure>
<%= image_tag investment.image.url(:large), <%= image_tag investment.image_url(:large),
title: investment.image_title, alt: investment.image.title %>
alt: investment.image_title %>
<figcaption class="text-right"> <figcaption class="text-right">
<em><%= investment.image_title %></em> <em><%= investment.image.title %></em>
</figcaption> </figcaption>
</figure> </figure>
<hr> <hr>

View File

@@ -219,6 +219,11 @@ en:
attributes: attributes:
max_per_day: max_per_day:
invalid: "You have reached the maximum number of private messages per day" invalid: "You have reached the maximum number of private messages per day"
image:
attributes:
attachment:
min_image_width: "Image Width must be at least %{required_min_width}px"
min_image_height: "Image Height must be at least %{required_min_height}px"
poll/voter: poll/voter:
attributes: attributes:
document_number: document_number:

View File

@@ -214,6 +214,11 @@ es:
attributes: attributes:
max_per_day: max_per_day:
invalid: "Has llegado al número máximo de mensajes privados por día" invalid: "Has llegado al número máximo de mensajes privados por día"
image:
attributes:
attachment:
min_image_width: "La imagen debe tener al menos %{required_min_width}px de largo"
min_image_height: "La imagen debe tener al menos %{required_min_height}px de alto"
poll/voter: poll/voter:
attributes: attributes:
document_number: document_number:

View File

@@ -36,6 +36,10 @@ Rails.application.routes.draw do
get '/welcome', to: 'welcome#welcome' get '/welcome', to: 'welcome#welcome'
get '/cuentasegura', to: 'welcome#verification', as: :cuentasegura get '/cuentasegura', to: 'welcome#verification', as: :cuentasegura
concern :imageable do
resources :images
end
resources :debates do resources :debates do
member do member do
post :vote post :vote
@@ -77,7 +81,7 @@ Rails.application.routes.draw do
resources :budgets, only: [:show, :index] do resources :budgets, only: [:show, :index] do
resources :groups, controller: "budgets/groups", only: [:show] resources :groups, controller: "budgets/groups", only: [:show]
resources :investments, controller: "budgets/investments", only: [:index, :new, :create, :show, :destroy] do resources :investments, controller: "budgets/investments", only: [:index, :new, :create, :show, :destroy], concerns: :imageable do
member do member do
post :vote post :vote
get :edit_image get :edit_image
@@ -229,7 +233,7 @@ Rails.application.routes.draw do
end end
end end
resources :budget_investments, only: [:index, :show, :edit, :update] do resources :budget_investments, only: [:index, :show, :edit, :update], concerns: :imageable do
resources :budget_investment_milestones resources :budget_investment_milestones
member { patch :toggle_selection } member { patch :toggle_selection }
end end

View File

@@ -320,11 +320,15 @@ FactoryGirl.define do
end end
trait :with_descriptive_image do trait :with_descriptive_image do
image { File.new("spec/fixtures/files/clippy.jpg") } association :image, factory: :image
image_title "Lorem ipsum dolor sit amet"
end end
end end
factory :image, class: 'Image' do
attachment { File.new("spec/fixtures/files/clippy.jpg") }
title "Lorem ipsum dolor sit amet"
end
factory :budget_ballot, class: 'Budget::Ballot' do factory :budget_ballot, class: 'Budget::Ballot' do
association :user, factory: :user association :user, factory: :user
budget budget

View File

@@ -29,8 +29,8 @@ feature 'Budget Investments' do
end end
scenario 'Index should show investment descriptive image only when is defined' do scenario 'Index should show investment descriptive image only when is defined' do
investment = create(:budget_investment, heading: heading) investment = FactoryGirl.create(:budget_investment, heading: heading)
investment_with_image = create(:budget_investment, :with_descriptive_image, heading: heading) investment_with_image = FactoryGirl.create(:budget_investment, :with_descriptive_image, heading: heading)
visit budget_investments_path(budget, heading_id: heading.id) visit budget_investments_path(budget, heading_id: heading.id)
@@ -39,7 +39,7 @@ feature 'Budget Investments' do
end end
within("#budget_investment_#{investment_with_image.id}") do within("#budget_investment_#{investment_with_image.id}") do
expect(page).to have_css("picture img[alt='#{investment_with_image.image_title}'][title='#{investment_with_image.image_title}']") expect(page).to have_css("picture img[alt='#{investment_with_image.image.title}']")
end end
end end
@@ -377,7 +377,7 @@ feature 'Budget Investments' do
visit budget_investment_path(budget_id: budget.id, id: investment_with_image.id) visit budget_investment_path(budget_id: budget.id, id: investment_with_image.id)
expect(page).to have_css("img[alt='#{investment_with_image.image_title}'][title='#{investment_with_image.image_title}']") expect(page).to have_css("img[alt='#{investment_with_image.image.title}']")
end end
scenario "Show back link contains heading id" do scenario "Show back link contains heading id" do

View File

@@ -29,7 +29,7 @@ describe Budget::Investment do
end end
end end
describe "#image and #image_title" do describe "#image and #image_title", :investment_image do
let(:investment_with_image) { build(:budget_investment, :with_descriptive_image) } let(:investment_with_image) { build(:budget_investment, :with_descriptive_image) }
it "should be valid" do it "should be valid" do