Graphs with Gruff (followup)
The solution from the source ;-) I checked it out and it now works as advertised, just add g.minimum_value = 0 to the Gruff::Bar before rendering it (g.to_blob).
Note that axis starting at zero.
| Without the minimum_value | With the minimum_value set to zero |
|
|
LAUNCH time.onrails.org, time tracking made simple! 2

We call it time.onrails.org. It’s a new FREE online time tracking product for the consultant and programmer that bills by the hour or works on multiple projects.
We (Lee and I) have been using it for awhile now to track our Rails consulting work. It’s really the fastest way to count your hours across multiple projects. And we tried many of the solutions out there.
See time.onrails.org for an overview or go straight to signup and be up and running in 5 seconds.
Let us know what you think at time@onrails.org.
Enjoy! Daniel
CSS Transparent Rollovers 3
I was trying to implement some rollover effects when I stumbled over this article at mandarindesign. I wrapped this functionality in the helper here after
1 2 3 4 5 6 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
1 2 3 4 5 6 7 8 | |
| Project | Dashboard | Charts |
|
|
|
|
Managing Rails Plugins dependencies 1
Rails has a nice plugin system allowing to add common code to a project. A plugin should really be independent from any other plugins. But we also use plugins to share code among different projects we are working on and our code depends on existing plugins. The Rails development team want’s to keep the plugin system simple and didn’t provide an explicit way to handle these dependencies, which I believe is a good decision. There is a solution. Simply name the plugins in order off the dependencies you have. Let’s assume you want to add “my_very_own_plugin” plugin that depends on the enumation_mixin, then simply organize the /vendor/plugins folder as follows, et Voila!:.
/myrailsapp
/vendor
/plugins
/01_acts_as_taggable
/01_enumations_mixin
/01_acts_as_versioned
/02_my_very_own_plugin
If we look at the Rails::Initializer we can see why this works. Note, this is only an extract of the full class that Rails provides to bootstrap your rails applicaton. The sort on line 4 here after allows this trick.
1 2 3 4 5 6 7 8 | |
A source code browser 1
Browse::Source is a simple source code browsing application. It’s 100% based on Collaboa, it’s mostly the source code browser functionality but uses the file system rather than connecting to subversion.
I recently got a request from Justin to have access to some ‘old’ rails code (flexonrails) we wrote a while ago, and also Todd asked for the source code of autumnriders. So I tried Collaboa but it requires to compile subversion from the source in order to have swig-rb. So I extracted the source code browser from Collaboa and removed the dependency on swig-rb. Now if all you need is to add simple source code browsing…then Browse::Source is what you need.
Well, we haven’t posted yet the two code bases mentionned above, but have a look at the source code browser source code Browse::Source
Graphs with Gruff 4
![]() |
|
Auto-login 29
One of my midnight Rails projects is a “time tracking” application for which I needed auto-login. You know, the “Remember me” check box so that you don’t have to login each time you visit the application. I found a nice article written by Matt McCray describing how this was implemented for TaskThis.com at http://www.mattmccray.com/archives/category/software/rails/taskthis/. Even further he provides the full source code for the application. I didn’t take directly his auto_login.rb module but was greatly inspired by it. I also used the Login Engine Plugin that was not providing this feature, maybe this changed, so it could be simpler, but how simple implementing the auto-login can be. Note these are not the full classes just pertinent code extracts.
1. Remember me
When the user login and checks the “Remember me” checkbox, the :save_login parameter is set, the User instance remember_me method invoked and the :auth_token cookie set.
class AccountController < ApplicationController
def login
case @request.method
when :post
if @session[:user] = User.authenticate(@params[:user_login], @params[:user_password])
flash['notice'] = "Login successful"
if @params[:save_login] == "1"
@session[:user].remember_me
cookies[:auth_token] = { :value => @session[:user].remember_token , :expires => @session[:user].remember_token_expires }
end
redirect_back_or_default :controller => "time"
else
flash.now['notice'] = "Login unsuccessful"
@login = @params[:user_login]
end
end
end
def logout
@session[:user].forget_me if @session[:user]
@session[:user] = nil
cookies.delete :auth_token
end
end2. login_from_cookie
The next time the user visits the website the “login_from_cookie” filter is triggered. This method checks that the user is not logged in and that the :auth_token cookie is set. If that’s the case the user matching the :auth_token is searched and the token_expiration verified the the user is automatically logged in. Et voila! I guess auto_login would be more appropriate as method name.
class ApplicationController < ActionController::Base
before_filter :login_from_cookie
def login_from_cookie
return unless cookies[:auth_token] && @session[:user].nil?
user = User.find_by_remember_token(cookies[:auth_token])
if user && !user.remember_token_expires.nil? && Time.now < user.remember_token_expires
@session[:user] = user
end
end
end3. the User class
The User class has two methods to set and remove the token from the database. It’s pretty secure as from the token the user cannot be identified without having the salt, the email, and the token expiration, which is most unlikely to be recreated. It could be even more secure by just encrypting some random unique identifier. The only issue I encountered was that the user class always forces the password validation and encryption when saving. For now I just bypass validation and encryption when setting and clearing the remember_me token.
class User < ActiveRecord::Base
def remember_me
self.remember_token_expires = 2.weeks.from_now
self.remember_token = Digest::SHA1.hexdigest("#{salt}--#{self.email}--#{self.remember_token_expires}")
self.password = "" # This bypasses password encryption, thus leaving password intact
self.save_with_validation(false)
end
def forget_me
self.remember_token_expires = nil
self.remember_token = nil
self.password = "" # This bypasses password encryption, thus leaving password intact
self.save_with_validation(false)
end
endinline RJS 2
In my previous article I was playing with RJS templates and finding easy way to generate them. Well Thomas just posted some new goodies see http://mir.aculo.us/articles/2006/01/21/new-inline-rjs-for-rails. For quick updates no need to have a separte .rjs file.
class UserController < ApplicationController
def refresh
render :update do |page|
page.replace_html('user_list',
:partial => 'user', :collection => @users)
page.visual_effect :highlight, 'user_list'
end
end
end.rjs and link_to_function 3
A neat little trick is that .rjs templates can be used to generate local javascript functions and be invoked without doing a server roundtrip.
playground_controller.rbclass PlaygroundController < ApplicationController
def rjs
response.headers['content-type'] = 'text/html'
end
end<html>
<head>
<%= javascript_include_tag :defaults %>
</head>
<body>
<h1 id='header'>Javascript function test</h1>
<%= link_to_function('Add', 'add_item()' ) -%> |
<%= link_to_function('Clear', 'clear_list()') %>
<ul id='list' />
<script type='text/javascript'>
<%= render :partial => 'functions', :type => 'rjs' %>
</script>
<script type='text/javascript'>
<%= # Note: following javascript is run when the page is loaded.
update_page do |page|
3.times { page.call 'add_item' }
end
%>
</script>
</body>
</html>The rjs method in the PlaygroundController set’s the content-type as we perform a render of an rjs from within a .rhtml and this seems to change the content-type, so we need to reset it.
_function.rjspage << 'function add_item() {'
page.insert_html :bottom, 'list', content_tag('li', 'item', :id => 'list_item' )
page.visual_effect :highlight, 'list', :duration => 3
page << '}'
page << 'function clear_list() {'
page.replace_html :list, ""
page.visual_effect :highlight, 'list', :duration => 3
page << '}'In the partial _function.rjs we insert the function declaration before writing to the page object. This allows us to invoke the add_item _ and clear_list _ methods using the link_to_function _ from in the .rhtml file. Note also in the .rhtml file we invoke directly the update_page method to insert three calls to add_item().
The generated html files looks like this
<html>
<head>
<script src="/javascripts/prototype.js" type="text/javascript"></script>
<script src="/javascripts/effects.js" type="text/javascript"></script>
<script src="/javascripts/dragdrop.js" type="text/javascript"></script>
<script src="/javascripts/controls.js" type="text/javascript"></script>
</head>
<body>
<h1 id='header'>Javascript function test</h1>
<a href="#" onclick="add_item(); return false;">Add</a> |
<a href="#" onclick="clear_list(); return false;">Clear</a>
<ul id='list' />
<script type='text/javascript'>
function add_item() {
new Insertion.Bottom("list", "<li id=\"list_item\">item</li>");
new Effect.Highlight('list',{duration:3});
}
function clear_list() {
Element.update("list", "");
new Effect.Highlight('list',{duration:3});
}
</script>
<script type='text/javascript'>
add_item();
add_item();
add_item();
</script>
</body>
</html>
Xml Builder
I created the new Playground category on this blog to expose various aspects regarding Ruby On Rails that I am exploring. It may raise more questions than provide answers, but in any case don’t hesitate to jump in and add your 2 cents.
The xml_builder method here after uses the render_to_string method to create some xml structure. The xml_string could as well have been in a separate .rxml file and and a simple _render statement instead of render_as_string could have saved one line of code. But hey, that’s what the playground is for!
class PlaygroundController < ApplicationController
def xml_builder
xml_string = <<-XML_END
xml.test do
xml.language(name)
xml.description("Rocks!")
end
XML_END
result = render_to_string(:inline => xml_string, :locals => { :name => 'Ruby'}, :type => :rxml)
render_text result
end
end
<test>
<language>Ruby</language>
<description>Rocks!</description>
</test>
