Waiting for ie, at least 7, but ideally all of them, to die
Tech stuff around computer programming, basically for web development, especially opensource. Topics will go round Ruby on Rails (git gems etc.), Ubuntu (admin and basic shell) and work organization (agile philosophy)
Tuesday, 25 September 2012
Monday, 6 August 2012
The easiest, fastest and safest way to get your ip address
Tuesday, 31 July 2012
Change the db with migrations on the fly
ActiveRecord::Migration.new.add_column :payments, :card_verification, :string, limit: 8 ActiveRecord::Migration.new.execute "full sql here"
Saturday, 14 July 2012
Coffescript rendering
The correct way to render html inside your XHR response in Rails.
app.showFlashMessages('<%=j flash_messages %>') $('.booking').replaceWith( '<%=j render @booking %>' ) app.myFunction( <%=raw array.map(&:to_json) %> ) # TODO: double check
Monday, 4 June 2012
backtrace_silencers to clean the development log from missing assets
# /config/initializers/backtrace_silencers.rb Rails.backtrace_cleaner.add_silencer { |line| line =~ /lib\/action_dispatch\/middleware\/static.rb/ } if Rails.env.development?
This simple line will clean up your development log to something like this:
[FTL] ActionController::RoutingError (No route matches [GET] "/assets/ecoologic/rooms/room_tb.png"): actionpack (3.2.5) lib/action_dispatch/middleware/static.rb:62:in `call'
This is only in development (or test?) as you usually don't use the static middleware in staging or production.
Thursday, 17 May 2012
mysql cheatsheet
# Print the query result into a file mysql> select * into outfile '/tmp/new.txt' from users; # show the current database mysql> select database();
Tuesday, 15 May 2012
Thursday, 3 May 2012
get out of the filter bubble
&pws=0to the end of your search URL in the search bar. Useful for SEO.
Disclaimer: You can't get out of all of the filters bubble.
Wednesday, 2 May 2012
define class methods in ruby (private too)
class Item def self.find(name) # ... end class << self alias :search :find end private_class_method :find # writing it below private is not enough end
Saturday, 28 April 2012
Friday, 27 April 2012
import a gem list
#!/usr/bin/ruby gem_list = <<GEM_LIST actionmailer (2.3.8) actionpack (2.3.8) activerecord (2.3.8) activeresource (2.3.8) activesupport (2.3.8) aws-s3 (0.6.3) barista (1.3.0) bistro_car (0.2.2) soap4r (1.5.8) therubyracer (0.10.2) will_paginate (2.3.16) xml-simple (1.1.2) GEM_LIST gem_list.split("\n").each do |line| gem = line.match(/^.+? /).to_s # with a space at the end versions = line.match(/\(.+\)/) # surrounded by parenthesis highest_version = line.match(/([\d\.]+)/).to_s puts `gem install #{gem} -v #{highest_version}` end
null_store cache for Rails 2
def initialize super # options parameter has been removed extend Strategy::LocalCache endand this is the call
# config/environments/development.rb require 'vendor/gems/activesupport/cache/null_store.rb' # could also go in environment.rb # [...] config.cache_store = :null_store # In Rails 3 it's simply :null
Update for rails 2.3.18:
Have your file in lib, rather than vendor/gems and have it referenced with full path, something like this:
require "#{Rails.root}/lib/activesupport/cache/null_store.rb"
If every other attempt fail, how about redirecting the cache to dev/null?
config.cache_store = :file_store, "/dev/null"
Thursday, 19 April 2012
Ruby 1.9.2 Goodies
[1,2,3].each_with_object(1).map(&:+) # => [2, 3, 4] # Same outcome, even shorter [1, 2, 3].map(&1.method(:+)) # => [2, 3, 4] # Thanks to rubyquicktips.com ######## even in 1.8 a = [[1,2,3],[2,3,4],[3,4,5]] # get the union: a.inject(a.first) { |f,x| f = f | x } # => [1, 2, 3, 4, 5] # get the intersection: a.inject(a.first) { |f,x| f = f & x } => [3]
Wednesday, 4 April 2012
Ruby Koan #183 about scoring project: The Greed Game
Here it goes!
class Greed def initialize(dice_faces) @dice_count = count_occurrences_in(dice_faces) @score = calculate_score! end attr_reader :score def calculate_score! @score = 0 @score += score_of_triple_1(1000) @score += score_of_other_triples(100) @score += score_of_5s(50) @score += score_of_1s(100) end private def score_of_5s(score) face_score(5, score) end def score_of_1s(score) face_score(1, score) end def score_of_other_triples(score_each) score_triples score_each, (2..6).to_a end # >>>>> here starts the meat def score_of_triple_1(score) score if @dice_count[1] >= 3 end def score_triples(score, faces) partial_score = 0 @dice_count.each_with_index do |times, face| next unless faces.include? face partial_score += score * face if times >= 3 end partial_score end # faces counted in triples are escluded def face_score(face, score = 0) times = @dice_count[face] score * (times % 3) end # <<<<< here ends the meat def count_occurrences_in(dice_faces) # nil for 0 which is not a face, then the 6 faces [nil,0,0,0,0,0,0].tap do |occurrences| dice_faces.each { |face| occurrences[face] += 1 } end end end def score(dice) # You need to write this method Greed.new(dice).score endEven considering only "the meat" of my class, the solution on github is still a few lines shorter... Hei, wait, I could implement the sandwitch in score_triple and count_times! I feel like Randy Marshall watching cooking programs!
Monday, 2 April 2012
restrict dates in datepicker with html data attribute
class DateDisabler constructor: (@only) -> beforeShowDay: (date) => if @only == date.getDate() [true, 'available', 'This date is a good date'] else [false, 'unavailable', 'This date is NOT good'] jQuery -> $('.datepicker').each (i, e) -> dates = $(e).data('only') disabler = new DateDisabler dates $(e).datepicker({beforeShowDay: disabler.beforeShowDay})and the haml that calls it:
.datepicker{data: {only: 5}}Please note the fat arrow in the beforeShowDay, I'll have a look at it soon. Of corse you want it to make it accept an array but that's quite easy and I'm going into it right now. For more complex solutions I recommend gazay/gon, which I know thanks to this railscast
Sunday, 1 April 2012
Realex RealVault ActiveMerchant implementation
# see: RealVault - Recurring Payments.pdf module ActiveMerchant::Billing class RealVault < RealexGateway # 7. on page 24 URL = 'https://check-doc.cgi' # 7.1 (Setup a new Payer) # Create a Profile for a payer using payer‐new # If the payer exists another one will be stored # payer is a hash (see self.test) def send_payer(payer, options = {}) requires! options, :order_id request = build_payer_new_request payer, options commit request, URL end # 7.2 (Payment method setup) # Store the Card details using Card‐New # If the card exists another one will be stored # card is a ActiveMerchant::Billing::CreditCard # options is a hash def send_card(card, options) requires! options, :order_id request = build_card_new_request card, options commit request, URL end # see self.test or send_x methods def store!(payer, card, options) send_payer_response = send_payer(payer, options) send_card_response = send_card(card, options) if send_payer_response.success? { :success? => (send_payer_response.success? && send_card_response.success?), :send_payer_response => send_payer_response, :send_card_response => send_card_response } end # ActiveMerchant::Billing::RealVault.test # will store the payer and the card in the test account # makes a purchase before as suggested by the doc. to make sure auth is ok # works out of the box def self.test timestamp = Time.new.to_s :number currency = 'EUR' firstname = 'John' surname = 'Smith' payerref = timestamp orderid = timestamp rv = ActiveMerchant::Billing::RealVault.new({:password => "pwd", :currency => currency, :rebate => "rebate", :account => "internettest", :login => "merchant_id", :gateway => "Realex"}) card = ActiveMerchant::Billing::CreditCard.new( :number => 'test_cc_number', :month => '12', :year => '2012', :type => 'visa', :first_name => firstname, :last_name => surname, :verification_value => '123') payer = { :type => 'Business', :ref => payerref, # 'smithj01' :title => 'Mr', :firstname => firstname, :surname => surname, :email => 'jsmith@acme.com', :company => 'Acme Inc', :address => { :line1 => '123 Fake St.', # :line2 # :line3 :postcode => '3', :city => 'Hytown', :county => 'Dunham', :country => 'Ireland', :country_code => 'IE' }, :phonenumbers => { :home => '55555555', :work => '+35317433923', :fax => '+35317893248', :mobile => '+353873748392', } } options = {:order_id => orderid, :currency => currency, :payerref => payer[:ref]} rv.purchase 777, card, options rv.store! payer, card, options # rv.send_payer payer, options # rv.send_card card, options end private def build_card_new_request(card, options) action = 'card-new' timestamp = Time.now.strftime '%Y%m%d%H%M%S' # same as to_s(:number), but not subjected to override orderid = sanitize_order_id options[:order_id] chname = "#{card.first_name}#{card.last_name}" expdate = card.year.to_s[2..3] + card.month.to_s sha1 = sha1from "#{timestamp}.#{@options[:login]}.#{orderid}...#{options[:payerref]}.#{chname}.#{card.number}" xml = Builder::XmlMarkup.new :indent => 2 xml.tag! :request, :timestamp => timestamp, :type => action do xml.tag! :merchantid, @options[:login] xml.tag! :orderid , orderid xml.tag! :card do xml.tag! :ref , card.type + timestamp[3..14] xml.tag! :payerref, options[:payerref] xml.tag! :number , card.number xml.tag! :expdate , expdate xml.tag! :chname , chname xml.tag! :type , CARD_MAPPING[card_brand(card).to_s] xml.tag! :issueno end xml.tag! :sha1hash, sha1 end end def build_payer_new_request(payer, options) action = 'payer-new' timestamp = Time.now.strftime '%Y%m%d%H%M%S' # same as to_s(:number), but not subjected to override orderid = sanitize_order_id options[:order_id] sha1 = sha1from "#{timestamp}.#{@options[:login]}.#{orderid}...#{payer[:ref]}" xml = Builder::XmlMarkup.new :indent => 2 xml.tag! :request, :timestamp => timestamp, :type => action do xml.tag! :merchantid, @options[:login] xml.tag! :account , @options[:account] xml.tag! :orderid , orderid xml.tag! :payer, :type => payer[:type], :ref => payer[:ref] do [:title, :firstname, :surname, :company].each do |tag| xml.tag! tag, payer.send('[]', tag) end xml.tag! :address do address = payer[:address] [:line1, :line2, :line3, :city, :county, :postcode].each do |tag| xml.tag! tag, address.send('[]', tag) end xml.tag! :country, address[:country], :code => address[:country_code] end xml.tag! :phonenumbers do phonenumbers = payer[:phonenumbers] [:home, :work, :fax, :mobile].each do |tag| xml.tag! tag, phonenumbers[tag] end end xml.tag! :email, payer[:email] xml.tag! :comments do xml.tag! :comment, nil, :id => 1 xml.tag! :comment, nil, :id => 2 end end xml.tag! :sha1hash, sha1 xml.tag! :comments do xml.tag! :comment, nil, :id => 1 xml.tag! :comment, nil, :id => 2 end end xml.target! end end endUnfortunately even the gem itself needed a slight change, due to constant priority order in Ruby (this wouldn't be necessary in java for example):
# Realex.rb in ActiveMerchant 1.9.4 # commit method in private section - def commit(request) + def commit(request, url = URL)
Saturday, 24 March 2012
Keeping the environment updated
rvm get latest --auto rvm install 1.9.3 gem update --system # 1.3.7 # that's it for downgrading
gem update bundler # which I actually keep in my Gemfile bundle update
Saturday, 17 March 2012
Useful Shell commands in Linux (terminal)
find . -name file_name # path first option without equal grep -rn string . --context=5 # path last # count the lines of ruby ( find ./ -name '*.rb' -print0 | xargs -0 cat ) | wc -l rails -e production rake x:y x:z RAILS_ENV=test # chain tasks and env is loaded only once rails c production --sandbox rails dbconsole -p'whatever' tailf log/development.log | grep -v ECONNREFUSED -E 'Processing|Render|Parameters' # show actions and templates only ssh user@host 'ls -l' scp -C user@host /tmp/db.sql /tmp/db.sql # -C will compress the data over the wire curl -Lk --user user:pwd --data "param1=value1¶m2=value2" http://url service --status-all netstat -an | grep "LISTEN " # check the open ports free -m # check the ram df -H # check the disk curl --user usr:pwd -Lkv --data "param1=value1¶m2=value2" www.url.com/post_here scp -C urs@url:/origin/ destination/
ncdu / # disk usage
Friday, 16 March 2012
Git cheatsheet
# Search for a word in log diff git log -S"def email_required" # display branches in activity order git for-each-ref --sort=-committerdate --format='%(committerdate:short) %(refname)' refs/heads refs/remotes # checkout previous branch git checkout - git checkout @{-1} # get rid of the latest changes and restore to the sha git checkout sha1 # undo latest pull git reset HEAD@{1} git checkout . # discard conflicting changes in a dir (after merge) git co --theirs dir/ # discard their changes git co --ours dir/ # discard our changes # stash git stash save "name of the stash" git stash apply git stash help # checkout a new branch from origin git checkout -b new origin/new # tags git tag "tag-name" git push --tags # bisect for debugging git bisect start git bisect bad git co 32c4bf6 # (known good sha) git bisect good # create a patch git format-patch -1 sha1 # and to apply it git am 0001-commit-name.patch # ignore a committed file # add the file to .gitignore git rm --cache your_file # ignore the repo git update-index --assume-unchanged .ruby-version # delete a remote branch git push origin --delete branch_name # rename a branch git branch -m old_name new_name # all your commits on any branch in the last x months git log --pretty=format:"%ad:%h:%B" --date=short --reverse --all --author=erik --since=1.day.ago # count the lines of code of your app git ls-files app/ | xargs wc -l # undo a merge that was already pushed: git revert -m 1 merge_hash # #Here great post on git tips .gitignore_global (add .rbenv-gemsets)
Here's my git config
Git style guide
Best practices
Monday, 12 March 2012
A Ruby on Rails developer environment
Then you'll need postgres
echo "-d=postgresql --skip-bundle -T" > ~/.railsrc # $ rvm gemset create opera_wbe # $ gem install bundler --no-rdoc --no-riNOTE: the `-T` option will change the `config/application.rb` as this following top group instead of loading `rails/all` (very nice!):
# Pick the frameworks you want: require "active_record/railtie" require "action_controller/railtie" require "action_mailer/railtie" require "active_resource/railtie" require "sprockets/railtie" # require "rails/test_unit/railtie" module OperaWbe class Application < Rails::Application # migration with numbers (001, 002, ...) in stead of timestamp config.active_record.timestamped_migrations = false # in production actually # prepend assets path # config.action_controller.asset_host = ASSETS_PATH # in development actually # Remove assets logging config.assets.logger = false # ~only~ one line each asset request # [...]Also I find the following files very useful
~/.irbrc # with global functions to call in the console ~/workspace/.rvmrc # which loads my @new gemset ~/workspace/every_app/.rvmrc # with the following...
rvm ruby-1.9.2-p290@new # with bundler and rails only rvm gemdir # show the gemdir everytime you change project
# .irbrc puts 'Using irb console helper functions from ~/.irbrc' # returns the list of methods not inherited from Object # it will not show methods overwritten from `Object.new` # eg: `y ml String.new` def ml(object) (String.public_methods - object.methods).sort endThen my prompt looks like this:
21:43:02-6950 - ~/workspace> cat ~/.bashrc [...] # some more ls aliases alias ll='ls -l' alias la='ls -A' alias lo='ls -o' # colorful, with time, history id and path (also in window title) # export PS1="\[\e]0;\w\a\]\e[1;36m\t-\! - \w>\e[m " export PS1="\[\e]0;\w\a\e[1;36m\]\t-\! - \w>\[\e[m\] " # TODO: git branch in prompt # ror workspace available everywhere export CDPATH=$CDPATH':/home/erik/workspace/' ## big bash history export HISTSIZE=20000 # append all commands to the history file, don't overwrite it at the start of every new session shopt -s histappend [[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm" # This loads RVM into a shell session. cd .And yes, I know, at the moment without without the git branch, it's messing with the color.
echo 'gem: --no-ri --no-rdoc' >~/.gemrc # never install gem docA couple of config for git, get the book here
[color] diff = true status = true branch = true [alias] co = checkoutSetup Sublime Text and customize it as such
Wednesday, 22 February 2012
Scrum, Agile according with @hamids
@hamids has the best introduction video on Scrum I've ever seen.
Sunday, 5 February 2012
blogger sucks
brush list
Configuring redis 2.4.7 on Ubuntu 10.04
TODO: this post is still a draft, if you're a visitor, please move on
* install *
not enough, then:
AAA! maybe I'd avoid adding it to the auto-execution list, which happens with the following command:
sudo update-rc.d redis-server defaults
run it with: sudo /etc/init.d/redis-server start
* customization *
/etc/sysctl.conf
sysctl vm.overcommit_memory=1 # to avoid reboot