ActiveScaffold: Batch Update

5 Comments

Today, I would like to talk about a topic which was kind of not existing in the world of activescaffold in the past: Batch Actions

which means trigger an action on more than one record.

In this post I will focus on update action. Actually, you will see it s quite easy to setup and it s quite powerful.

Batch Actions are not part of activescaffold core, if you would like to use them you have to install another plugin: ActiveScaffoldBatch

rails plugin install git://github.com/vhochstein/active_scafffold_batch.git 

Let me show you some of the possibilities you have using players controller of my little howto app. I recommend using jquery for my examples, cause datetime examples will work out of the box. (Prototype needs calendar_date_select plugin for this.)

Firstly, we have to enable players controller for batch updates:

class PlayersController < ApplicationController
  active_scaffold :player do |conf|
    ....
    conf.actions << :batch_base 
    conf.actions << :batch_update 
    ....
  end
end

If you hit reload in your browser you should see a new collection action ‘batch’, which will open a submenu ‘Update’ on hover.
Please click on that link and you will see a batch_update form.

Change team for all players:

  • Change value of corresponding select box to ‘Replace’
  • select new team
  • press Batch Update Button

Set name attribute to null:

  • Change value of corresponding select box to ‘Null’
  • press Batch Update Button

Revert prev action and set name attribute to a name you like:

  • Change value of corresponding select box to ‘Replace’
  • Enter new name
  • press Batch Update Button

Increase salary for all players by 5%.

  • Change value of corresponding select box to ‘+’
  • Enter 5
  • Select % instead of abs
  • press Batch Update Button

Change Birthday of all players. Should be one week earlier.

  • Change value of corresponding select box to ‘-‘
  • Enter 1
  • Select week
  • press Batch Update Button

All examples so far changed all records, but for sure you can define a search condition. Batch Update will only process records, which fullfill current search conditions.

For example: search for some players, which you want to set to injured state.

However, sometimes it s not so easy to define a search condition, which covers all records you would like to update. If you are facing such an issue you might want to combine with mark action.

First step is to enable mark action in players controller

class PlayersController < ApplicationController
  active_scaffold :player do |conf|
    ....
    conf.actions << :mark
    ....
  end
end

As well we have to add mark route in routes.rb:

resources :players do 
  as_routes 
  post :mark_all, : on => :collection 
end 

That s it, now you ve got the option in batch update form to just affect marked records.

Wish you all a happy new year.

Advertisements

ActiveScaffold: Actionlinks and Icons

7 Comments

Lets talk about your possibilities to use Icons for actionlinks.
I will use ‘fire’ action_link introduced in Actionlink response and ignore to demonstrate the options.

First option: “prefix” you label with an icon using css

That s quite easy, you just have to take a look at css file of activescaffold to find the pattern (new and search actions are already using this option).

.active-scaffold tr.record td.actions a.fire {
background: url("../../../images/fire.png") 0 0 no-repeat;
padding-left: 19px;
background-position: 1px 50%;
background-repeat: no-repeat;
}

Second option: replace your label with an icon using css

There are several techniques available and all of them have their pro s and con s.
I will just show you one of them, which requires to set action_links label to an empty string.

PlayersController:

  conf.action_links.add 'fire', :label => '', :confirm => 'are_you_sure', :type => :member, :method => :put, :position => false

css

.active-scaffold td.actions a.fire {
display:block;
width: 18px;
height: 18px;
background: url("../../../images/fire.png") 0 0 no-repeat;
background-position: center center;
} 

Third option: Using an image tag

Remove any css code you ve added for the first two options and change your action_link configuration in players controller

  conf.action_links.add 'fire', :image => {:name => 'fire.png', :size => '16x16'}, :confirm => 'are_you_sure', :type => :member, :method => :put, :position => false

If you want to use this option to change active_scaffolds native actionlinks such as edit, you can do that as well.
Add the following to your application_controller.rb:

..
ActiveScaffold::Config::Update.link = ActiveScaffold::DataStructures::ActionLink.new('edit', :image => {:name => 'update.png', :size => '16x16'}, :type => :member, :security_method => :update_authorized?)
class ApplicationController < ActionController::Base
..

ActiveScaffold: Confirmation of Actionlinks

Leave a comment

Today I was called by a user stating that something really bad happened. He clicked an actionlink accidently and now data is a mess.
Well after some investigation I ve asked him: Why did you even press ok in confirmation dialog?
The answer was quite a surprise for me cause he told me that there was nt any confirmation dialog.
First thought of any developer, user is lying, but well sadly I have to admit that he was right. He had javascript disabled and I had to accept that apparently activescaffold was performing the action without a confirmation.

I ve fixed that today. If you update your activescaffold to latest version, you are save.
However, application will display missing routing error in these special cases.

Let me show you how you may change your application to work as expected if javascript is disabled.
In my post Actionlink response and ignore I ve described an easy way to respond to actions triggered by an actionlink. I will use it as a base for my example.

First step: Adding a new route

 put :fire, : on => :member
 get :fire, : on => :member 

As an alternative you might also add non resource routes, it s important to add them BEFORE the resource routes.

match 'players/:id/fire' => 'players#fire', :via => [:get, :put] 
resources :player

Second step: Rewrite action method fire in players controller

def fire 
  process_action_link_action do |record| 
    begin 
      record.update_attributes!(:salary => 0) 
      self.successful = true 
      flash[:info] = 'player fired' 
    rescue 
      self.successful = false 
      flash[:error] = 'Internal Error'
    end 
  end 
end 

New Method process_action_link_action is doing all the magic and in addition should further simplify your action management.