jump to navigation

Adding environment variables to cron via whenever November 24, 2009

Posted by John Dewey in Crontab, Plugins & Gems.
2 comments

I wanted my users’ cron to run under zsh, so it picks up the .zshenv — which contains additional environment variables, my rake task required.

Can add the following to schedule.rb. This will work with any ENVIRONMENT=variable.

### schedule.rb
env ‘SHELL’, ‘/usr/bin/zsh’

Changing the default error text in the Rails reCAPTCHA plugin July 15, 2009

Posted by John Dewey in Configuration, Example, Plugins & Gems, Rails.
add a comment

I couldn’t find information on changing the default “Captcha response is incorrect, please try again.” text returned by the reCAPTCHA Rails plugin.

This gist uses Rails 2.2’s internationalization (I18n) to change the message.

gem install that (well kind-of) April 11, 2009

Posted by John Dewey in Code, Plugins & Gems.
add a comment

Geminstallthat is a pretty groovy name, which reidmix came up with. What would be really geeky is a gem named ‘that‘, which allows you to read my blog. I didn’t feel like dealing with rubyforge (to get the non-githuby gem name) , so here is a sneak peek at that.

$ gem sources -a http://gems.github.com
$ sudo sudo gem install retr0h-that
Successfully installed retr0h-that-0.0.0
1 gem installed
Installing ri documentation for retr0h-that-0.0.0...
Installing RDoc documentation for retr0h-that-0.0.0...
$ that

It will display all posts from the time the gem was built to Time.now.

Simple_admin met a Pieman November 7, 2008

Posted by dougmcinnes in Code, Plugins & Gems, Rails, Rake, Ruby.
Tags: , , , , ,
3 comments

Simple_admin is a Ruby on Rails plugin I created at the Los Angeles Times that morphed into a collabrative effort between Dewey, Reid and myself as it traveled between projects and functionality was added.  I’ve just released it to our latimes github account: http://github.com/latimes/simple_admin/tree/master

The basic premise is to give a simple way of managing login usernames and passwords without a database.  The data is stored in a YAML file in the application with the passwords encrypted by String’s crypt() method.

To add users to the file there’s an included rake task: admin:add_user.  The username and password are passed as parameters:

rake admin:add_user username=mrwalrus password=mahbukkit

Rake will append the user to the login.yaml file or create a new one.  The default location for this file is config/admin/login.yml but can be overridden by setting the LOGIN_FILE environment variable in your application.  If you set the LOGIN_FILE differently in your different rails environment files you can have different usernames and passwords for development and production.

There’s also a rake task for adding multiple users at the same time from a text file list, giving them all random passwords.

To get the plugin to actually use Basic HTTP authentication to ask for usernames and passwords add this to your application controller:

include SimpleAdmin
before_filter :check_basic_http_credentials

Like all filters you can add conditions:

before_filter :check_basic_http_credentials, :only => :login

When including SimpleAdmin in your controller you also get access to the authenticate(username, password) method which can be used for custom login pages.  For example:

def login
  if authenticate(params[:username], params[:password])
    session[:admin] = true
    redirect_to main_page
  end
end

Also included in the plugin is some code for marking different servers as “admin” servers and a way for a rails application to check to see if he’s an admin or not and change its behavior.  We used this on one application running on multiple boxes so we could turn off page caching on the admin-marked boxes so the administration WYSIWYG pages wouldn’t be cached and sent to non-admin users (that would be a big oops).

Subselector, Moneypenny November 1, 2008

Posted by reidmix in ActiveRecord, Code, Database, Example, Monkey Patch, Plugins & Gems, Rails.
Tags: , , , , ,
2 comments

Building on Josh and Damon‘s idea of Hacking a Subselect in ActiveRecord, I wondered if you could bake this kind of functionality into ActiveRecord.  So Doug and I went digging into the rails code, and came up with a plugin that adds subselects to ActiveRecord which we call Subselector.

So far, it only works on the Hash version of conditions.

On a column you wish to perform a subselect, pass a hash with :in, :not_in, :equals, or :not_equals as the only key.  The value is any of the options you normally would pass to ActiveRecord find.  Notice that we make sure to select a single column with the :select option:

Critic.find(:all, :conditions => { :id => {:in => {:select => :id, :conditions => {:active => true} } } })

Although the example may be contrived, here, we are looking for a critics that are in a set of active critics. The SQL:

select * from critics where id in (select id from critics where active = false)

You can see by default it runs the subselect on the table of outer select.  It gets more interesting you want to run a query on another ActiveRecord model:

Critic.find(:all, :conditions => { :id => {:in => {:model => :rankings, :select => :critic_id, :conditions =>
  {:week => 39} } } })

Here we set :model to :rankings.  Rankings is the ActiveRecord model to perform the find, notice we select the :critic_id column, the SQL is:

select * from critics where id in (select critic_id from rankings where week = 39)

And of course you can always just pass a string as a value to the subselect:

Critic.find(:all, :conditions => { :id => {:not_in => 'select id from critics where active = true' } })

Here’s how subselector can be used with the original example:

Post.find(:all, :conditions => :id => {:in => { :select => :post_id, :conditions => {:blog_id => self.id}, :order => "published_at DESC", :limit => options[:limit] || 10, :offset => options[:offset])} }, :order => "published_at DESC")

UPDATE: Subselector now likes Condition Arrays and Named Bind Variables.

Just pass the hash as a bind variable and specify the type (in/equals) of subselect in the string, make sure to enclose your ‘?’ inside parentheses:

Critic.find(:all, :conditions => ['id in (?)', {:select => :id, :conditions => 'active = true' }])
Critic.find(:all, :conditions => ['id not in (?)', {:select => :id, :conditions => {:active => false} }])
Critic.find(:all, :conditions => ['id in (?)', {:model => :rankings, :select => :critic_id, :conditions => {:week => 39} }])

As you can see, you can format the subselect hash just as above and can specify another model to run the subselect on. If you prefer to use named bind variable hashes, they still work (yay) as you would expect. And you can assign the subselect using them:

Critic.find(:all, :conditions => ['id in (:subselect)', {:subselect => {:select => :id, :conditions => {:active => false} } }])

UPDATE 2: Now with no ActiveRecord breakage

We’ve run the rails ActiveRecord tests without any problems. Let me know if you find any problems.

Include Health October 29, 2008

Posted by reidmix in Example, Plugins & Gems, Rails.
Tags: , , , , ,
1 comment so far

I created a little plugin to make it easier to offer health check URLs in all our applications called Health.  These URLs are a necessity for our SysAdmins to hook into Big Brother or Nagios.  These monitoring systems systematically poll an application at this URL to check the status of the application.

To get started, install the health plugin and include it in your Application controller:

class ApplicationController < ActionController::Base
  include Health
end
&#91;/sourcecode&#93;

That's it.  You should be able to navigate to <a href="http://localhost:3000/check_heath">http://localhost:3000/check_heath</a>. Health sets up the named route '<span class="s1">check_health' and</span> by default it will check the connection of the database by running a "<strong>select 1</strong>" SQL statement.  If all goes well you should see "SERVERUP".  If there's a problem with the query you will see "DBDOWN" or an 500 error depending on the level of problem.  You can turn off the DB checking (our SysAdmins wanted it):


ApplicationController < ActionController::Base
  include Health
  health_check :with_db => false
end

One more trick, it does is handle any additional / custom checks that you may require. Pass a block, Proc, or a symbol that represents the name of the method to the health_check directive:

ApplicationController < ActionController::Base include Health health_check do |controller| controller.has_donut? || "no donut" end end [/sourcecode] In this case, assuming the controller has a method called has_donut? which does not return false or nil, you will see the “SERVERUP” message, otherwise you will see what was last evaluated in a message like “PROCDOWN no donut”

And you can mix and match all three types of blocks, Procs, and symbols — more examples are in the README.

Railsolver – now with wildcard host resolution September 12, 2008

Posted by John Dewey in Monkey Patch, Plugins & Gems, Rails, Ruby.
add a comment

I was watching the Subdomains Railscast. Ryan listed a few ways to point subdomains at your development system, and I thought Railsolver should support wildcards.

Updates are on github, along with an updated README and bugs :). I also added some Railsolver props on the Railscast page.


This plugin will “hijack” Ruby host(s) resolver aka(resolv-replace.rb), allowing programmatic host file resolution (including wildcard host resolution).™

Railsolver – programmatic Rails host resolution September 9, 2008

Posted by John Dewey in Plugins & Gems, Rails, Ruby.
add a comment

Ever want to to programmatically control your applications name resolution? Railsolver takes a stab at doing just that.


This plugin will “hijack” Ruby host(s) resolver aka(resolv-replace.rb),
allowing programmatic host file entries.

Hosts can be added globally or overridden per environment inside a YAML configuration file. You can also embed ERB.

See the README for usage.

controlling memcached with Phusion’s daemon_controller September 6, 2008

Posted by John Dewey in Code, Deployment, Memcached, Plugins & Gems, Rails, Ruby.
add a comment

I am working on an application that utilizes memcached, and want to develop against a locally running instance. Previously, we pointed our development environment to a sandboxed memcached cluster, which can be slow depending on time of day, location, and network. I typically mock external resources, however, I like a living memcache.

This post describes a way to start memcached automatically with script/server, and is a continuation of the daemon_controller memcached configuration post.

As the Phusion guys pointed out. Pulling code — and not worrying about configuration is AWESOME! This is especially true in the development environment.

phusion-daemon-controller.png

Adding this to development.rb will automatically start and stop memcached via ‘script/console’ and ‘script/server’. SAs maintain the daemons in the other environments via SMF, nor am I interested in maintaining those environments (did that … done that).

daemon_controller memcached configuration September 4, 2008

Posted by John Dewey in Configuration, Deployment, Memcached, Plugins & Gems, Rails, Ruby.
2 comments

The Phusion guys created a sweeet library (daemon_controller) to control servers or daemons. I created a daemon_memcache class which controls memcached.

Memcached can be controlled programatically by:

DaemonMemcache.instance.start
DaemonMemcache.instance.running?
DaemonMemcache.instance.stop

Will show you how to utilize this class to start/stop Memcached via ‘script/server’ in a follow-up post.