Rails Bad Practices #2 - using Time.now in scope
Ever wondered how to get your time-dependent scopes to act like bunch of lunatics?
do this:
class User < ActiveRecord::Base
scope :active, where(:activated_at.gt => Time.now)
end
and your list of active users will stub every time you restart your app. Cool!
Of course, this great trick can’t be achieved with this:
class User < ActiveRecord::Base
scope :active, lambda{ where(:activated_at.gt => Time.now) }
end
Rails Bad Practices #1 - sql injection.
Sql injection is a very nice trick, however it’s really hard to achieve with Rails. This few simple lines of code allow all of your users to execute sql whatever way they want:
#app/models/user.rb
class User < ActiveRecord::Base
scope :very_clever_scope, lambda{|name_or_id| where("name = #{name_or_id} OR id=#{name_or_id}")
end
#app/controllers/users_controller.rb
class UsersController < ApplicationController
def show
#uber clever params[:id] backwards compability
User.very_clever_scope(params[:id]).find(:first)
end
end
And now you can relax and enjoy DROP ALL TABLES queries.
Recursively Setting Deep Hash Value - revisited
This great tip allows you to recursively set hash value - really useful thing when you have to generate complicated hash.
One gotcha that i found about this is, that after generating SuperHash instance you must remember about reseting the default value of this hash.
Consider this:
class SuperHash < Hash
def initialize
super { |h, k| h[k] = SuperHash.new }
end
end
> suuper = SuperHash.new #=> {}
> suuper['mad']['sheep'] = false
> suuper['mad']['sheep'] #=> false
> suuper['mad']['cow'] #=> {}
> supper['calm']['sheep'] #=> {}
Notice that every undefined key, no matter how deeply nested will return empty hash instead of nil. This was a bit misleading for me since i used SuperHash instance to check complex conditions
> !!{} #=> true
Whatever i did, all conditions were always true :)
The solution of course w’d be to reset SuperHash default after generating full structure:
> suuper = SuperHash.new #=> {}
> suuper['mad']['sheep'] = false
> suuper.default = nil #=> nil
> supper['calm']#=> nil
However, as my colleague pointed out, reseting default only on suuper wont fix the issue, since nested hashes inside still have their own defaults. What we need to do is complete rewrite of our superhash back to hash again. This can be easily achievied with this:
> suuper = SuperHash.new #=> {}
> suuper['mad']['sheep'] = false #=> false
> suuper = {}.update(suuper)
> supper['calm'] #=> nil
> suuper['mad']['cow'] #=> nil
> supper['calm']['sheep'] #=> Error
And now we are golden :)
RVM readline library problems?
4 steps to resolve:
1. sudo apt-get install ncurses-dev
2. cd $HOME/.rvm/src/ruby-1.9.2-p180/ext/readline
3. ruby extconf.rb — —with-readline-dir=”$HOME/.rvm/usr”
4. make install
More information:
http://beginrescueend.com/packages/readline/
Pow
Since most of us use macs and most of us work on few projects at the same time we really appreciate what 37signals did. Go and check out Pow project.
humans.txt
There is an interesting initiative coming from Spain. The idea is to put humans.txt file containing information about people who have contributed to building the site. More at humanstxt.org
Never run rails 3 application on ruby 1.8.7
You must update to 1.9.2. RoR3 applications on old ruby are slow. REALLY SLOW.
Incompatible character encodings with serialized fileds in ruby 1.9.2
Watchout for serialized fields in ActiveRecord. On ruby 1.9.2 strings in such fields get saved with ASCII-8BIT encoding, not with UTF-8 as you w’d expect.