Commit b761ce0c222a31aa36f03493c6eb054a508a7a0b

Authored by JoenioCosta
1 parent ea8173bc

ActionItem348: add option to upload image when editing categories

git-svn-id: https://svn.colivre.coop.br/svn/noosfero/trunk@1817 3f533792-8f58-4932-b0fe-aaf55b0a4547
app/controllers/my_profile/profile_editor_controller.rb
@@ -12,12 +12,7 @@ class ProfileEditorController < MyProfileController @@ -12,12 +12,7 @@ class ProfileEditorController < MyProfileController
12 def edit 12 def edit
13 @profile_data = profile 13 @profile_data = profile
14 if request.post? 14 if request.post?
15 - profile.image || profile.build_image  
16 if profile.update_attributes(params[:profile_data]) 15 if profile.update_attributes(params[:profile_data])
17 - if !params[:image].blank? && !params[:image][:uploaded_data].blank? && !profile.image.update_attributes(params[:image])  
18 - flash[:notice] = _('Could not upload image')  
19 - return  
20 - end  
21 redirect_to :action => 'index' 16 redirect_to :action => 'index'
22 end 17 end
23 end 18 end
app/helpers/application_helper.rb
@@ -567,4 +567,8 @@ module ApplicationHelper @@ -567,4 +567,8 @@ module ApplicationHelper
567 # observe_field(state_field_name, :update => city_field_name, :url => { :controller => 'geography', :action => 'cities' }, :with => 'state_id') 567 # observe_field(state_field_name, :update => city_field_name, :url => { :controller => 'geography', :action => 'cities' }, :with => 'state_id')
568 # end 568 # end
569 569
  570 + def file_field_or_thumbnail(label, image, i)
  571 + display_form_field( label, (render :partial => (image && image.valid? ? 'shared/show_thumbnail' : 'shared/change_image'), :locals => { :i => i, :image => image }) )
  572 + end
  573 +
570 end 574 end
app/models/category.rb
@@ -32,6 +32,8 @@ class Category < ActiveRecord::Base @@ -32,6 +32,8 @@ class Category < ActiveRecord::Base
32 32
33 has_many :products, :through => :enterprises 33 has_many :products, :through => :enterprises
34 34
  35 + acts_as_having_image
  36 +
35 def recent_articles(limit = 10) 37 def recent_articles(limit = 10)
36 self.articles.recent(limit) 38 self.articles.recent(limit)
37 end 39 end
app/models/product.rb
@@ -6,8 +6,6 @@ class Product < ActiveRecord::Base @@ -6,8 +6,6 @@ class Product < ActiveRecord::Base
6 validates_uniqueness_of :name, :scope => :enterprise_id 6 validates_uniqueness_of :name, :scope => :enterprise_id
7 validates_numericality_of :price, :allow_nil => true 7 validates_numericality_of :price, :allow_nil => true
8 8
9 - has_one :image, :as => :owner  
10 -  
11 after_update :save_image 9 after_update :save_image
12 10
13 acts_as_searchable :fields => [ :name, :description, :category_full_name ] 11 acts_as_searchable :fields => [ :name, :description, :category_full_name ]
@@ -18,13 +16,7 @@ class Product < ActiveRecord::Base @@ -18,13 +16,7 @@ class Product < ActiveRecord::Base
18 product_category.full_name(" ") 16 product_category.full_name(" ")
19 end 17 end
20 18
21 - def image_builder=(img)  
22 - if image && image.id == img[:id]  
23 - image.attributes = img  
24 - else  
25 - build_image(img)  
26 - end  
27 - end 19 + acts_as_having_image
28 20
29 def save_image 21 def save_image
30 image.save if image 22 image.save if image
app/models/profile.rb
@@ -70,7 +70,7 @@ class Profile < ActiveRecord::Base @@ -70,7 +70,7 @@ class Profile < ActiveRecord::Base
70 has_many :articles, :dependent => :destroy 70 has_many :articles, :dependent => :destroy
71 belongs_to :home_page, :class_name => Article.name, :foreign_key => 'home_page_id' 71 belongs_to :home_page, :class_name => Article.name, :foreign_key => 'home_page_id'
72 72
73 - has_one :image, :as => :owner 73 + acts_as_having_image
74 74
75 has_many :consumptions 75 has_many :consumptions
76 has_many :consumed_product_categories, :through => :consumptions, :source => :product_category 76 has_many :consumed_product_categories, :through => :consumptions, :source => :product_category
app/views/categories/_form.rhtml
1 <%= error_messages_for 'category' %> 1 <%= error_messages_for 'category' %>
2 2
3 -<% labelled_form_for 'category' do |f| %> 3 +<% labelled_form_for 'category', @category, :html => { :multipart => true} do |f| %>
4 <% if @category.new_record? %> 4 <% if @category.new_record? %>
5 <% if @category.parent %> 5 <% if @category.parent %>
6 <%= hidden_field_tag('parent_id', @category.parent.id) %> 6 <%= hidden_field_tag('parent_id', @category.parent.id) %>
@@ -13,6 +13,11 @@ @@ -13,6 +13,11 @@
13 <%= select_color_for_category %> 13 <%= select_color_for_category %>
14 14
15 <%= f.text_field 'name' %> 15 <%= f.text_field 'name' %>
  16 +
  17 + <% f.fields_for :image_builder, @category.image do |i| %>
  18 + <%= file_field_or_thumbnail(_('Image:'), @category.image, i) %>
  19 + <% end %>
  20 +
16 <% button_bar do %> 21 <% button_bar do %>
17 <%= submit_button('save', _('Save'), :cancel => {:action => 'index'}) %> 22 <%= submit_button('save', _('Save'), :cancel => {:action => 'index'}) %>
18 <% end%> 23 <% end%>
app/views/manage_products/_change_image.rhtml
@@ -1,8 +0,0 @@ @@ -1,8 +0,0 @@
1 - <%= file_field_tag("product[image_builder][uploaded_data]") %>  
2 -  
3 - <br/>  
4 -  
5 - <%= link_to_function(_('Cancel'), nil, :id => 'cancel-change-image-link', :style => 'display: none') do |page|  
6 - page['change-image-link'].show  
7 - page['change-image'].replace_html ''  
8 - end %>  
app/views/manage_products/_form.rhtml
@@ -4,7 +4,9 @@ @@ -4,7 +4,9 @@
4 <%= display_form_field( _('Name:'), f.text_field(:name) ) %> 4 <%= display_form_field( _('Name:'), f.text_field(:name) ) %>
5 <%= display_form_field( _('Price:'), f.text_field(:price) ) %> 5 <%= display_form_field( _('Price:'), f.text_field(:price) ) %>
6 <%= display_form_field( _('Description:'), f.text_area(:description, :rows => 10) ) %> 6 <%= display_form_field( _('Description:'), f.text_area(:description, :rows => 10) ) %>
7 - <%= display_form_field( _('Image:'), (render :partial => @product.image && @product.image.valid? ? 'show_thumbnail' : 'change_image') ) %> 7 + <% f.fields_for :image_builder, @product.image do |i| %>
  8 + <%= file_field_or_thumbnail(_('Image:'), @product.image, i) %>
  9 + <% end %>
8 10
9 <div id='subcategories'> 11 <div id='subcategories'>
10 <%= render :partial => 'subcategories' %> 12 <%= render :partial => 'subcategories' %>
app/views/manage_products/_show_thumbnail.rhtml
@@ -1,11 +0,0 @@ @@ -1,11 +0,0 @@
1 - <%= image_tag(@product.image.public_filename(:thumb)) %>  
2 -  
3 - <br/>  
4 -  
5 - <%= link_to_function(_('Change image'), nil, :id => 'change-image-link') do |page|  
6 - page['change-image'].replace_html :partial => 'change_image'  
7 - page['change-image-link'].hide  
8 - page['cancel-change-image-link'].show  
9 - end %>  
10 -  
11 - <div id='change-image'> </div>  
app/views/profile_editor/edit.rhtml 0 → 100644
@@ -0,0 +1,18 @@ @@ -0,0 +1,18 @@
  1 +<h1><%= _('Edit profile') %></h1>
  2 +
  3 +<%= error_messages_for :profile %>
  4 +
  5 +<% labelled_form_for :profile_data, @profile, :html => { :multipart => true } do |f| %>
  6 + <%= render :partial => partial_for_class(@profile.class), :locals => { :f => f } %>
  7 + <h1><%= _('Change your picture') %></h1>
  8 + <% f.fields_for :image_builder, @profile.image do |i| %>
  9 + <%= file_field_or_thumbnail(_('Image:'), @profile.image, i) %>
  10 + <% end %>
  11 + <%= select_categories(:profile_data, _('Select the categories of your interest'), 1) %>
  12 + <% button_bar do %>
  13 + <%= submit_button('save', _('Save'), :cancel => {:action => 'index'}) %>
  14 + <%= button(:back, _('Back to control panel'), :controller => 'profile_editor') %>
  15 + <% end %>
  16 +<% end %>
  17 +
  18 +<%# = generate_form :info, @info, {...} %>
app/views/profile_editor/index.rhtml
@@ -6,8 +6,6 @@ @@ -6,8 +6,6 @@
6 6
7 <% file_manager do %> 7 <% file_manager do %>
8 8
9 - <%= file_manager_button(_('Change your picture'), profile_icon(@profile, :portrait), :controller => 'profile_editor', :action => 'change_image') %>  
10 -  
11 <%= file_manager_button(_('Edit Profile'), 'icons-app/edit-profile.png', :controller => 'profile_editor', :action => 'edit') %> 9 <%= file_manager_button(_('Edit Profile'), 'icons-app/edit-profile.png', :controller => 'profile_editor', :action => 'edit') %>
12 10
13 <%= file_manager_button(_('Pending tasks'), 'icons-app/todo.png', :controller => 'tasks', :action => 'index') %> 11 <%= file_manager_button(_('Pending tasks'), 'icons-app/todo.png', :controller => 'tasks', :action => 'index') %>
app/views/shared/_change_image.rhtml 0 → 100644
@@ -0,0 +1,8 @@ @@ -0,0 +1,8 @@
  1 + <%= i.file_field( :uploaded_data, { :onchange => 'updateImg(this.value)' } ) %>
  2 +
  3 + <br/>
  4 +
  5 + <%= link_to_function(_('Cancel'), nil, :id => 'cancel-change-image-link', :style => 'display: none') do |page|
  6 + page['change-image-link'].show
  7 + page['change-image'].replace_html ''
  8 + end %>
app/views/shared/_show_thumbnail.rhtml 0 → 100644
@@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
  1 + <%= image_tag(image.public_filename(:thumb)) %>
  2 +
  3 + <br/>
  4 +
  5 + <%= link_to_function(_('Change image'), nil, :id => 'change-image-link') do |page|
  6 + page['change-image'].replace_html :partial => 'shared/change_image', :locals => { :i => i, :image => image }
  7 + page['change-image-link'].hide
  8 + page['cancel-change-image-link'].show
  9 + end %>
  10 +
  11 + <div id='change-image'> </div>
config/environment.rb
@@ -96,6 +96,7 @@ require &#39;acts_as_filesystem&#39; @@ -96,6 +96,7 @@ require &#39;acts_as_filesystem&#39;
96 require 'acts_as_searchable' 96 require 'acts_as_searchable'
97 require 'acts_as_having_boxes' 97 require 'acts_as_having_boxes'
98 require 'acts_as_having_settings' 98 require 'acts_as_having_settings'
  99 +require 'acts_as_having_image'
99 require 'hacked_after_create' 100 require 'hacked_after_create'
100 101
101 # load a local configuration if present, but not under test environment. 102 # load a local configuration if present, but not under test environment.
lib/acts_as_having_image.rb 0 → 100644
@@ -0,0 +1,20 @@ @@ -0,0 +1,20 @@
  1 +module ActsAsHavingImage
  2 +
  3 + module ClassMethods
  4 + def acts_as_having_image
  5 + has_one :image, :as => 'owner'
  6 + self.send(:include, ActsAsHavingImage)
  7 + end
  8 + end
  9 +
  10 + def image_builder=(img)
  11 + if image && image.id == img[:id]
  12 + image.attributes = img
  13 + else
  14 + build_image(img)
  15 + end
  16 + end
  17 +
  18 +end
  19 +
  20 +ActiveRecord::Base.extend(ActsAsHavingImage::ClassMethods)
test/functional/categories_controller_test.rb
@@ -81,5 +81,11 @@ class CategoriesControllerTest &lt; Test::Unit::TestCase @@ -81,5 +81,11 @@ class CategoriesControllerTest &lt; Test::Unit::TestCase
81 end 81 end
82 end 82 end
83 83
  84 + should 'be able to upload a file' do
  85 + assert_difference Category, :count do
  86 + post :new, :category => { :name => 'new category', :image_builder => { :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png') } }
  87 + assert_equal assigns(:category).image.filename, 'rails.png'
  88 + end
  89 + end
84 90
85 end 91 end
test/functional/profile_editor_controller_test.rb
@@ -72,7 +72,7 @@ class ProfileEditorControllerTest &lt; Test::Unit::TestCase @@ -72,7 +72,7 @@ class ProfileEditorControllerTest &lt; Test::Unit::TestCase
72 cat1 = Environment.default.categories.build(:name => 'top category'); cat1.save! 72 cat1 = Environment.default.categories.build(:name => 'top category'); cat1.save!
73 cat2 = Environment.default.categories.build(:name => 'sub category', :parent => cat1); cat2.save! 73 cat2 = Environment.default.categories.build(:name => 'sub category', :parent => cat1); cat2.save!
74 person = create_user('test_user').person 74 person = create_user('test_user').person
75 - get :edit_categories, :profile => 'test_user' 75 + get :edit, :profile => 'test_user'
76 assert_response :success 76 assert_response :success
77 assert_template 'edit_categories' 77 assert_template 'edit_categories'
78 assert_tag :tag => 'input', :attributes => {:name => 'profile_object[category_ids][]'} 78 assert_tag :tag => 'input', :attributes => {:name => 'profile_object[category_ids][]'}
@@ -225,7 +225,7 @@ class ProfileEditorControllerTest &lt; Test::Unit::TestCase @@ -225,7 +225,7 @@ class ProfileEditorControllerTest &lt; Test::Unit::TestCase
225 should 'show image field on edit profile' do 225 should 'show image field on edit profile' do
226 person = create_user('testuser').person 226 person = create_user('testuser').person
227 get :edit, :profile => 'testuser' 227 get :edit, :profile => 'testuser'
228 - assert_tag :tag => 'input', :attributes => { :name => 'image[uploaded_data]' } 228 + assert_tag :tag => 'input', :attributes => { :name => 'profile_data[image_builder][uploaded_data]' }
229 end 229 end
230 230
231 should 'show categories field on edit profile' do 231 should 'show categories field on edit profile' do
@@ -251,7 +251,7 @@ class ProfileEditorControllerTest &lt; Test::Unit::TestCase @@ -251,7 +251,7 @@ class ProfileEditorControllerTest &lt; Test::Unit::TestCase
251 should 'be able to upload an image' do 251 should 'be able to upload an image' do
252 person = create_user('test_profile').person 252 person = create_user('test_profile').person
253 assert_nil person.image 253 assert_nil person.image
254 - post :edit, :profile => 'test_profile', :image => { :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png')} 254 + post :edit, :profile => 'test_profile', :profile_data => { :image_builder => { :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png') } }
255 assert_not_nil assigns(:profile).image 255 assert_not_nil assigns(:profile).image
256 end 256 end
257 end 257 end
test/unit/category_test.rb
@@ -376,4 +376,13 @@ class CategoryTest &lt; Test::Unit::TestCase @@ -376,4 +376,13 @@ class CategoryTest &lt; Test::Unit::TestCase
376 # assert_includes c1.people, person 376 # assert_includes c1.people, person
377 #end 377 #end
378 378
  379 + should 'have image' do
  380 + assert_difference Category, :count do
  381 + c = Category.create!(:name => 'test category1', :environment => Environment.default, :image_builder => {
  382 + :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png')
  383 + })
  384 + assert_equal c.image(true).filename, 'rails.png'
  385 + end
  386 + end
  387 +
379 end 388 end