ActionMailer Timeouts February 22, 2009
Posted by John Dewey in Code, Monkey Patch, Rails.add a comment
The following gist contains a monkeypatch allowing configurable timeouts on ActionMailer. Since ActionMailer is blocking, it is nice to set a reasonable timeout, rather than wrapping each of your ActionMailer calls with a Timeout (alarm). I actually monkeypatch all of ‘net/smtp’, so just rescue ‘Timeout::Error’ where needed.
chef-solo VPS provisioning February 21, 2009
Posted by John Dewey in Apache, Automation, Chef, Code, Configuration.add a comment
I probably built a naive chef solo configuration. I also know I could have used one of the many “Ready Stack” solutions VPS providers are creating. However, I like my systems setup a particular way.
Take a peek the configuration is pretty cool. The code is on github.
Ideally chef would have built my system from the ground up, installing ruby, libs, etc… Since I do not control this piece, there are a few prerequisites to setting up chef.
Once complete, drop in your virtualhost, and deploy your code. This is not intended as zero-conf. Merely a standard base configuration for all of my hosts.
icanhasrspec – lolspek sneak peek February 17, 2009
Posted by John Dewey in Example, RSpec.add a comment
requiring javascript_helper outside rails December 30, 2008
Posted by John Dewey in Code, Example, TestUnit.add a comment
I wanted to fix the tests for css_browser_selector, when updating it to support a rails 2.2.0 change with concat.
However, I would get the following error.
>> require 'action_view/helpers/javascript_helper' TypeError: wrong argument type Symbol (expected Proc)
As it turns out you must require ActiveSupport first, since the JavaScriptHelper requires Sym#to_proc.
Also, ActionView::Helpers::JavascriptHelper alias was removed – yay tests!
Am I rspec-tarded? December 29, 2008
Posted by John Dewey in Code, Example, RSpec, Ruby.1 comment so far
So I want to test the xml declaration and xhtml doctype of my application layout.
I ended up with this pastie.
Does anyone know of a way to accomplish this using rspec’s have_tag/with_tag? I’m not too fond of the regexp solution in the pastie.
Rails log rotations via rsyslog December 25, 2008
Posted by John Dewey in Code, Configuration, Deployment, Example, Rails.2 comments
I have a client that logs their rails logs via syslog, for consumption by pl_analyze. I am not a fan of this, and will probably change it at some point. When using Apache, I’ll typically configure rails to use a rotatelogs pipe.
However, in this case, to avoid changing legacy infrastructure around the logs, I setup rsyslog to do the rotations for me. Hopefully this will be useful to someone else.
This assumes your rails app already logs to syslog.
Added the following to /etc/rsyslog.conf.
Simple_admin met a Pieman November 7, 2008
Posted by dougmcinnes in Code, Plugins & Gems, Rails, Rake, Ruby.Tags: admin, crypt, HTTP auth, los angeles times, password, yaml
2 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,nly => :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: Rails, select, sql, subselect, named bind variables, bind variables
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},
rder => "published_at DESC", :limit => options[:limit] || 10,
ffset => options[:offset])} },
rder => "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.