Running RCOV, and having it complain about a p articular plugin that it should not have been looking at in the first place, made me want to find a way to exclude it. In my usual practical fashion, I hit google up for a quick way to exclude the unwanted plugin.
Here it is re-posted from Dan Mange’s Blog…
config.plugins = Rails::Initializer.new(config).send(:find_plugins, config.plugin_paths).map {|path| File.basename(path)}
config.plugins -= %W(plugin_one plugin_two)UPDATE: JJ Barrett has an update for Rails 2.x… http://www.jjbarrett.net/archives/plugin-ordering-and-exclusion-in-rails-20
config.plugins = config.plugin_locators.map do |locator|
locator.new(Rails::Initializer.new(config)).plugins
end.flatten.map{|p| p.name.to_sym}
config.plugins -= [:do_not_load_plugin_1, :do_not_load_plugin_2]‘jaap’ wrote a rake task to convert your Rails application from using Gettext translation into the new I18n support, which is really great!
WARNING: Before you run the new rake task rake gettext_to_i18n:transform, read “So How Do You Fix It?” below
OK, so you’ve followed along in the article and now you want to test out your new localization system. Problem is when you try to start the server up script/server you get this error message:
/Users/cblackburn/Source/ruby/bols/lib/active_support/memoizable.rb:71:in `path': can't modify frozen object (TypeError)…or something similar.
What happened? Since you have frozen Rails and the rake task does not exclude the frozen vendor/rails directory, it modified memoizable.rb in ActiveSupport causing this error.
So How Do You Fix It?
Do one of the following:
- Backup lib/active_support/memoizable.rb before you run the rake task, then restore it after.
- Restore lib/active_support/memoizable.rb using your SCM.
For this project in my case it was
svn revert lib/active_support/memoizable.rbBetween the time your migration files get generated and deploying to production with your new application you will likely need to add indexes to one or more of your tables. How do you know which tables need indexes and which fields in those tables to index?
Here are some tips to help figure out where the likely bottlenecks will occur with regard to your database tables:
- Always index @*_id@ foreign_key fields. Let’s say you have 2 tables, @users@ and @addresses@. You may have migration file code in @./db/migrate@ that looks like this:
...
def self.up
create_table "users", :force => true do |t|
t.column :login, :email :string
end
end
... ...
def self.up
create_table "addresses", :force => true do |t|
t.column :user_id :integer
t.column :address :string
end
end
...You will always want to index the foreign_key @user_id@, with few exceptions. So simply add the @add_index@ line like this:
...
def self.up
create_table "addresses", :force => true do |t|
t.column :user_id :integer
t.column :address :string
end
add_index "addresses", :user_id
end
...This will facilitate much faster associations when you lookup related models like this view code:
<%=h user.address.address %>
# OR as the case may be...
<%=h address.user.email %>- As a rule of thumb index any column for which you will be using to lookup a row or set of rows. For example, if you will be doing something like this:
u = User.find_by_email('test@example.com')… then you will want to index the email field.
- Run explain plans on your associations to determine where indexes would benefit the queries. Now this one is more tricky unless you know about the query_analyzer plugin. This nifty little tool will automatically dump out explain plans into your logfiles in development mode that look like this example from the README file:
# development.log P Load (0.008669) => SELECT p.* FROM p INNER JOIN d ON p.id = d.p_id WHERE (d.p_id = 2 AND ((d.type = 'P'))) Analyzing P Load select_type | key_len | type | Extra | id | possible_keys | rows | table | ref | key ---------------------------------------------------------------------------------------------------- SIMPLE | | ALL | Using where | 1 | | 74 | d | | SIMPLE | 4 | eq_ref | Using where | 1 | PRIMARY | 1 | p | d.p_id | PRIMARY
Now what this tells you is that the table @d@ is missing an index because MySQL is having to look at “ALL” the records. Whenever you see a @type@ of @ALL@ and/or @possible_keys@ is empty it should be a red flag telling you to index something.
If we had followed tips 1 and 2 this explain plan would be much different, showing reference types of @ref@ and @eq_ref@ which is typically a good thing.
For more information see the README file here: http://agilewebdevelopment.com/plugins/query_analyzer.
If you are getting an error message like this:
ActiveRecord::StatementInvalid: Mysql::Error: Table configurable_settings doesn't exist
… when trying to use Jacob Radford’s http://agilewebdevelopment.com/plugins/acts_as_configurable
Just do this:
./script/console development
ConfigurableSetting.create_table
Of course replace ‘development’ above with whatever environment you need.
If you are experiencing the error: “undefined class/module MyClass” when fetching data from memcached, be assured that you are not alone. It is a known bug and the simplest way I know of to get around it is to reference the class or classes right before you retrieve data from the cache.
For example, if the following code causes the problem:
if not (genres = Cache.get(key))
genres = Genre.find(:all, :condition => "platform_id = 1")
Cache.put(key, genres, 60*60*24) # cache for 1 day
end… then this code will work around it:
Genre
if not (genres = Cache.get(key))
genres = Genre.find(:all, :condition => "platform_id = 1")
Cache.put(key, genres, 60*60*24) # cache for 1 day
endNotice the ‘Genre’ reference before the if statement. Some have reported success by using the ‘model’ statement within the controller, however that is deprecated. This workaround will get you going again.
Have you ever wanted to look at the call stack without raising an exception to do it?
caller.each {|c| puts c}If you are getting this error message when trying to use RoR ActiveRecord, there is a simple workaround… read on.
MySQL has a problem with how Rails sends the username and password when initiating the connection through the socket.
A quick fix/workaround is to create a MySQL user without a password. Add it to your database.yml file and restart your Mongrel/Webrick server.
Recently, while working on one of our client’s projects, I found myself needing to validate credit card numbers. Of course the most secure way to do it is to use your merchant services (i.e., Verisign PayFlowPro, etc.). However most often those services cost anywhere from $15/month and 3 cents per transaction and up.
For most purposes the business wants to simply prevent its customers from fat-fingering their credit card numbers when typing it in. But there are several pieces of information that can be validated for any given credit card like: expiration date, billing address, security code, cardholder’s name, etc.
For our purposes we simply wanted to protect customers from their own fat fingers. The Luhn algorithm does nicely for that purpose, and for the most part, keeps honest people honest.
Here it is using Ruby:
def validate_credit_card(number)
reverse_card_num = number.reverse
sum = 0
reverse_card_num.scan(/./).each_with_index do |digit, index|
digit = digit.to_i
digit *= 2 if index % 2 != 0
if digit.to_s.length == 2
first_num = digit.to_s[0..0]
second_num = digit.to_s[1..1]
digit = first_num.to_i + second_num.to_i
end
sum += digit
end
pass = sum % 10 == 0 ? true : false
endTo use it just pass in your 15-16 digit credit card number and it will return a boolean for pass or fail.
When I have some more time I’ll post some additional validation code that CBCI currently uses for credit cards.
We needed a convenient way to store a series of values in a single field. A bitfield would not do because it would only allow a value of 1 or 0 for each field, and we wanted to be able to store at least 3 values for each field.
So I found Gabriel Gironda’s acts_as_bitfield plugin and made a few tweaks. ActsAsBytefield is the result. It allows storage of 256 values in each field, or 255 discrete values ranging from 0-255 (unsigned char or byte) for each value in a MySQL varchar(255) field.
NOTE: Gabriel’s site has been down for some time. My own repository has also been down but is now back up. Sorry for the inconvenience.
Values greater than 255, or less than 0 wrap around. For example, setting a bytefield column to -1 will actually set it to 255, and setting it to -2 will actually set it to 254, etc.
Installation
./script/plugin install acts_as_bytefield
OR
./script/plugin install https://svn.cbciweb.com/svn/plugins/acts_as_bytefield
Documentation (RDoc)
rake rdoc
Testing
The tests require rspec
rake test
Usage
- Create a string column in your table - varchar(255)
- Add this directive to your model:
acts_as_bytefield :bytefield_column_name, :fields => [:field_name_one, :field_name_two]You will then be able to use the model in the following manner, for example:
class SomeModel < ActiveRecord::Base
acts_as_bytefield :bfield, :fields => [:test, :production]
end
obj = SomeModel.new(:test => 1)
obj.test #=> 1
obj.test? #=> 1
obj.production? #=> 0
obj.test = 0
obj.production = 65
obj.save
obj.test? #=> 0
obj.production? #=> 65
# The field that's storing the value:
obj.bfield #=> "\000A"Thought I had posted this last year but can’t seem to find it, so here it is again:
#!/usr/bin/env ruby
require File.dirname(__FILE__) + '/../../config/boot'
# Restart Applicable Passenger Instance
filename = "#{RAILS_ROOT}/tmp/restart.txt"
File.open(filename, 'w') {|f| f.write('restart passenger') }Save this file as: ./scripts/process/reaper, then deploy and it will restart your passenger instance.

