WIP
This commit is contained in:
committed by
Senén Rodero Rodríguez
parent
886431b43d
commit
614ff79ba1
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
|
|||||||
14
app/models/concerns/imageable.rb
Normal file
14
app/models/concerns/imageable.rb
Normal 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
48
app/models/image.rb
Normal 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
|
||||||
@@ -53,16 +53,17 @@
|
|||||||
data: {js_url: suggest_tags_path} %>
|
data: {js_url: suggest_tags_path} %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<%= f.fields_for :image do |builder| %>
|
||||||
|
|
||||||
<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.form.image_label"), class:'button' %>
|
<%= f.label :attachment, t("budgets.investments.form.image_label"), class:'button' %>
|
||||||
<p><%= investment_image_file_name(@investment) %></p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<% if @investment.errors.has_key?(:image) %>
|
<% if @investment.errors.has_key?(:attachment) %>
|
||||||
<div class="small-12 column">
|
<div class="small-12 column">
|
||||||
<div class="image-errors">
|
<div class="image-errors">
|
||||||
<small class="error"><%= errors_on_image(@investment)%></small>
|
<small class="error"><%= errors_on_image(@investment)%></small>
|
||||||
@@ -71,8 +72,9 @@
|
|||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<div class="small-12 column">
|
<div class="small-12 column">
|
||||||
<%= f.text_field :image_title %>
|
<%= f.text_field :title %>
|
||||||
</div>
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
<% unless current_user.manager? %>
|
<% unless current_user.manager? %>
|
||||||
|
|
||||||
|
|||||||
@@ -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? %>
|
||||||
|
<div class="float-right">
|
||||||
<%= link_to t("budgets.investments.edit_image.form.remove_button"),
|
<%= link_to t("budgets.investments.edit_image.form.remove_button"),
|
||||||
remove_image_budget_investment_path(@investment.budget, @investment),
|
remove_image_budget_investment_path(@investment.budget, @investment),
|
||||||
class: "button hollow alert",
|
class: "button hollow alert",
|
||||||
method: :delete,
|
method: :delete,
|
||||||
data: { confirm: t("budgets.investments.edit_image.form.remove_alert") } %>
|
data: { confirm: t("budgets.investments.edit_image.form.remove_alert") } %>
|
||||||
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -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 %>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user