back

Keeping controllers empty with faux attributes

Say we have a website where the customers have 1 week free trials. Say that there are also administrators who want to occasionally reset the trial period of a customer.

The lots of code way

We could do this with a controller action and a link:

1
2
3
4
5
6
7
8
9
class UsersController

  def reset_trial
    @user = User.find(params[:id])
    @user.reset_trial!
    redirect_to @user
  end

end

However, this brings with it the burden of adding a route and controller action specifically for this method.

The barely any code way

Instead, you can just use a fake attribute. Define an attribute setter on User, and then just make a small form in the view to set it.

1
2
3
4
5
# view
<% form_for @user do |f| %>
  <%= f.hidden_field :reset_trial, :value => true %>
  <%= f.submit 'Reset trial' %>
<% end %>
1
2
3
4
5
6
7
# user.rb
class User < ActiveRecord::Base
  attr_accessor :reset_trial
  def reset_trial=(value)
    # whatever logic to reset the trial
  end
end

This avoids burdening the controller with any knowledge about what we’re doing. Instead it just flows through the normal update action. There are obviously tradeoffs, in that we are simply moving the code from the controller to the view and the model, however I often use this to keep controllers dumb.

September 21, 2009