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 def edit
13 13 @profile_data = profile
14 14 if request.post?
15   - profile.image || profile.build_image
16 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 16 redirect_to :action => 'index'
22 17 end
23 18 end
... ...
app/helpers/application_helper.rb
... ... @@ -567,4 +567,8 @@ module ApplicationHelper
567 567 # observe_field(state_field_name, :update => city_field_name, :url => { :controller => 'geography', :action => 'cities' }, :with => 'state_id')
568 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 574 end
... ...
app/models/category.rb
... ... @@ -32,6 +32,8 @@ class Category < ActiveRecord::Base
32 32  
33 33 has_many :products, :through => :enterprises
34 34  
  35 + acts_as_having_image
  36 +
35 37 def recent_articles(limit = 10)
36 38 self.articles.recent(limit)
37 39 end
... ...
app/models/product.rb
... ... @@ -6,8 +6,6 @@ class Product < ActiveRecord::Base
6 6 validates_uniqueness_of :name, :scope => :enterprise_id
7 7 validates_numericality_of :price, :allow_nil => true
8 8  
9   - has_one :image, :as => :owner
10   -
11 9 after_update :save_image
12 10  
13 11 acts_as_searchable :fields => [ :name, :description, :category_full_name ]
... ... @@ -18,13 +16,7 @@ class Product < ActiveRecord::Base
18 16 product_category.full_name(" ")
19 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 21 def save_image
30 22 image.save if image
... ...
app/models/profile.rb
... ... @@ -70,7 +70,7 @@ class Profile < ActiveRecord::Base
70 70 has_many :articles, :dependent => :destroy
71 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 75 has_many :consumptions
76 76 has_many :consumed_product_categories, :through => :consumptions, :source => :product_category
... ...
app/views/categories/_form.rhtml
1 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 4 <% if @category.new_record? %>
5 5 <% if @category.parent %>
6 6 <%= hidden_field_tag('parent_id', @category.parent.id) %>
... ... @@ -13,6 +13,11 @@
13 13 <%= select_color_for_category %>
14 14  
15 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 21 <% button_bar do %>
17 22 <%= submit_button('save', _('Save'), :cancel => {:action => 'index'}) %>
18 23 <% end%>
... ...
app/views/manage_products/_change_image.rhtml
... ... @@ -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 4 <%= display_form_field( _('Name:'), f.text_field(:name) ) %>
5 5 <%= display_form_field( _('Price:'), f.text_field(:price) ) %>
6 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 11 <div id='subcategories'>
10 12 <%= render :partial => 'subcategories' %>
... ...
app/views/manage_products/_show_thumbnail.rhtml
... ... @@ -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 @@
  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 6  
7 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 9 <%= file_manager_button(_('Edit Profile'), 'icons-app/edit-profile.png', :controller => 'profile_editor', :action => 'edit') %>
12 10  
13 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 @@
  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 @@
  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 96 require 'acts_as_searchable'
97 97 require 'acts_as_having_boxes'
98 98 require 'acts_as_having_settings'
  99 +require 'acts_as_having_image'
99 100 require 'hacked_after_create'
100 101  
101 102 # load a local configuration if present, but not under test environment.
... ...
lib/acts_as_having_image.rb 0 → 100644
... ... @@ -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 81 end
82 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 91 end
... ...
test/functional/profile_editor_controller_test.rb
... ... @@ -72,7 +72,7 @@ class ProfileEditorControllerTest &lt; Test::Unit::TestCase
72 72 cat1 = Environment.default.categories.build(:name => 'top category'); cat1.save!
73 73 cat2 = Environment.default.categories.build(:name => 'sub category', :parent => cat1); cat2.save!
74 74 person = create_user('test_user').person
75   - get :edit_categories, :profile => 'test_user'
  75 + get :edit, :profile => 'test_user'
76 76 assert_response :success
77 77 assert_template 'edit_categories'
78 78 assert_tag :tag => 'input', :attributes => {:name => 'profile_object[category_ids][]'}
... ... @@ -225,7 +225,7 @@ class ProfileEditorControllerTest &lt; Test::Unit::TestCase
225 225 should 'show image field on edit profile' do
226 226 person = create_user('testuser').person
227 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 229 end
230 230  
231 231 should 'show categories field on edit profile' do
... ... @@ -251,7 +251,7 @@ class ProfileEditorControllerTest &lt; Test::Unit::TestCase
251 251 should 'be able to upload an image' do
252 252 person = create_user('test_profile').person
253 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 255 assert_not_nil assigns(:profile).image
256 256 end
257 257 end
... ...
test/unit/category_test.rb
... ... @@ -376,4 +376,13 @@ class CategoryTest &lt; Test::Unit::TestCase
376 376 # assert_includes c1.people, person
377 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 388 end
... ...