So Rails Templates have been around now since 2.3.0. I have finally found the time to dig in and enjoy them, after watching Ryan Bates’ screencast episode 148.
Feel free to use my base_template or any of my rails generators which can be found at github.com/cblackburn. My template is pretty basic, but I’ve wanted a way to do this kind of thing for years. I used to write shell scripts to setup my default Rails applications. This is so much nicer!
To use it just do this:
rails appname -m http://github.com/cblackburn/rails-templates/raw/master/base_template.rb
# Plugins
plugin 'exception_notifier', :git => 'git://github.com/rails/exception_notification.git'
# Gems
if yes?("Will you need to paginate?")
gem "mislav-will_paginate", :lib => 'will_paginate'
end
rake("gems:install", :sudo => true)
# Generators
generate :app_layout
if yes?("Will you be using MySQL?")
db_password = ask("What is the MySQL password for root?")
puts "Type 'y' and Enter to overwrite the current database.yml file."
generate( "database_yml_mysql #{db_password}") # This uses my own generator
end
if yes?("Do you need Authlogic?")
generate :authlogic # This uses my authlogic-generator
end
generate :controller, "home index"
route "map.root :controller => :home"
# General cleanup
rake "db:create:all"
rake "db:migrate"
run "echo TODO > README"
run "rm -f public/index.html"
# Files
file ".gitignore", <<-END
.DS_Store
log/*.log
log/*.pid
tmp/**/*
config/database.yml
db/*.sqlite3
END
# Git
git :init
git :add => "."
git :commit => "-m 'initial commit'"
If you decide to use this you’ll also want to take a look at my generators: http://github.com/cblackburn/personal-rails-generators
I have found myself needing to sort a hash collection often, by a value within the hashes. The last instance where I needed this was to sort an aggregated result set of multiple union queries. So sorting with an order by clause would not work across the unions.
The solution is below. I pass a sort_clause into the method that would look like this company_name asc or company_name desc.
def stats(sort_clause)
# queries, etc.
...
find_by_sql(sql).each do |acct|
aid = acct.id.to_i
results[aid] = {} unless results[aid]
month = acct.monthname
case (month)
when 'last'
results[aid][:spend_last] = acct.spend.to_f
when 'this'
results[aid][:spend_this] = acct.spend.to_f
when 'total'
results[aid][:company_name] = acct.company_name
results[aid][:balance] = acct.bal.to_f
results[aid][:campaigns] = acct.campaign_count.to_i
results[aid][:keywords] = acct.keyword_count.to_i
end
end
sort_col, order = sort_clause.split(' ')
logger.debug("sort_clause: #{sort_clause}")
results = results.sort_by{ |item|
item[1][sort_col.intern]
}
if (order =~ /desc/i)
results.reverse!
end
results
endWe 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"
