namespace :deploy do desc "Hot deploy, only usable w/o migrations" task :hot do update reroll end desc "Rolling restart for Mongrels" task :reroll, :roles => :app_admin do (8000..8005).each do |port| sudo "monit -g app unmonitor mongrel_#{port}" sudo "/usr/local/ec2onrails/bin/mongrel_stop --only #{port}" sudo "/usr/local/ec2onrails/bin/mongrel_start --only #{port}" sudo "wget --no-verbose localhost:#{port}/stat && rm -f stat" # this should block until the mongrel has booted sudo "monit -g app monitor mongrel_#{port}" end end end
New plugin! From the README:
What It Is
A robust mass assignment method with a small and obvious syntax.
The normal mass assignment protection comes from attr_protected and attr_accessible. There are a many problems with this approach:
- Often never implemented, leaving a wide-open system. And once implemented, easy to forget when adding new attributes, leading to bugs (in an attr_accessible system) or security holes (in an attr_protected system).
- Restricts coding syntax. You can’t easily use update_attributes() or attributes= because your whitelist/blacklist gets in your own way.
- Not contextual. The list of allowed attributes can’t change to accomodate different user permissions or situations.
This plugin’s solution is to let you specify an obvious list of allowed attributes when you mass assign attributes.
- The list of allowed attributes is in your controller at calltime, so it’s easier to remember and update (it’s not a hidden, magical system).
- The list of allowed attributes is optional, so it doesn’t get in your way.
- Your controller can easily enforce permissions by evaluating the current user (Admin Controller) or the current situation (creates vs updates).
Example
Let’s take a very plausible situation where you would want three separate lists of allowed attributes. You have users that sign up to your application. But after they have signed up, they may not change their username. Admins, however, may manually change a username as needed.
class UsersController < ApplicationController
def create
@user = User.new
# during signup a user may pick a username
@user.assign(params[:user], [:username, :email, :password, :password_confirmation])
@user.save!
...
end
def update
@user = User.find(params[:id])
# username is no longer accepted later
@user.assign(params[:user], [:email, :password, :password_confirmation])
@user.save!
...
end
end
class Admin::UsersController < ApplicationController
before_filter :admin_required
def update
@user = User.find(params[:id])
# admins, on the other hand, may change the username as needed, but may not set passwords
@user.assign(:params[:user], [:username, :email])
@user.save!
...
end
endGet it here: http://github.com/cainlevy/mass_assignment/tree/master
It’s a common challenge: once a user has logged in, or registered, or finished resetting a password, where do you send him? Ideally you send him to where he wants to be, but is that the same place as where he entered the login or registration pipeline? Has it changed since then?
The common solution packaged with restful_authentication is to set and maintain session[:return_to]. This requires setting save points by either tracking where the user was trying to go (request.url) or where the user just came from (request.referer). This works pretty well, but I’m trying something different—cookies. It just feels … simpler.
The code looks like this:
class ApplicationController < ActionController::Base
before_filter :set_save_point
def set_save_point
if request.get?
cookies[:last_page] = {
:value => request.url,
:expires => 30.minutes.from_now
}
end
end
def landing_page(default = nil)
cookies[:last_page] || default
end
def return_or_continue_to(default = nil)
redirect_to landing_page(default)
end
endThen for any action where you take sidetracks (logging in, registering, resetting password, etc.) you simply skip the set_save_point filter. Like so:
class SessionsController < ApplicationController
skip_before_filter :set_save_point
end
class UsersController < ApplicationController
skip_before_filter :set_save_point, :only => [:new, :create]
endBeautiful. Simple. Set and forget. No database access. Is it better than session[:return_to]? I’m still deciding …