Seems like the most trivial thing to do, but I could not find any information about changing the sort order when sending multipart emails from devise.
First, create a custom mailer for devise https://github.com/plataformatec/devise/wiki/How-To:-Use-custom-mailer
Then add parts_order to the default hash.
1 2 3
| class DeviseMailer < Devise::Mailer
default from: 'user@domain.com', parts_order: [ "text/plain", "text/html" ]
end |
Thats it. And oh, this works for any other mailer to.
Posted in
Programming at March 27th, 2013.
No Comments
Tagged with
devise,
mailer,
Rails. Written by:
stjernstrom
When you have a table with serialized columns active record will always treat them as dirty. It can create unnecessary overhead when just incrementing a simple counter.
Fortunately rails has a method that just update the counter and nothing else.
apidock: update_counters
If you have a Movie model with a counter named like_count and you would like to increment it by one you would use the following method.
1
| Movie.update_counters id, :like_count => 1 |
As a bonus you also get a locking
Posted in
Programming,
Rails at May 19th, 2012.
No Comments
Tagged with
activerecord,
Rails,
tip. Written by:
stjernstrom
If you are on OSX you can learn Capistrano to talk. And when you do, he can tell you when your deploy is done.
Just add the following task to your deploy.rb
1 2 3
| task :do_speak do
system("/usr/bin/say -r 250 -v Zarvox 'Sir, your #{rails_env} deploy is done'")
end |
And hook it up to run after deploy
1
| after 'deploy', 'do_speak' |
Now use your imagination, and add more words to Capistrano’s vocabulary
If you are using Linux or windows you can use espeak to get the same results
Cheers!
Posted in
Programming,
Rails,
Ruby at May 19th, 2012.
No Comments
Tagged with
capistrano,
deploy,
Ruby. Written by:
stjernstrom
Today I decreased my Ruby On Rails boot time by ~60%, Yay!
(All credit goes to funny-falcon for the patches and Burke who posted the Gist)
I removed 26 gems from my Gemfile and I noticed a boost with a couple of seconds. From that I begun searching for large Gemfile problems and I stumbled on this gist https://gist.github.com/1688857
It a pretty long page, so I will just summarize how I got my 60%
I use ruby 1.9.3-p125 and rbenv and ruby-build for handling ruby.
First we need to create a manifest file for our new patched ruby
Create a file named ruby-1.9.3-perf with the following content
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| build_package_combined_patch() {
local package_name="$1"
{
curl 'https://raw.github.com/gist/1859082/performance_and_backport_gc.patch' | patch -p1
autoconf
./configure --prefix="$PREFIX_PATH" $CONFIGURE_OPTS
make -j 8
make install
} >&4 2>&1
}
require_gcc
install_package "yaml-0.1.4" "http://pyyaml.org/download/libyaml/yaml-0.1.4.tar.gz"
install_package "ruby-1.9.3-p125" "http://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.3-p125.tar.gz" combined_patch |
When we have our manifest file in place we can use ruby-build to build ruby
1
| ruby-build ./ruby-1.9.3-perf ~/.rbenv/versions/ruby-1.9.3-p125 |
And here is my final results!
1 2 3 4 5 6 7 8 9 10 11 12 13
| Before
time -p bundle exec rake environment
real 6.81
user 5.93
sys 0.85
After
time -p bundle exec rake environment
real 3.75
user 2.82
sys 0.91 |
All credit goes to funny-falcon for the patches and Burke who posted the Gist.
Posted in
Rails,
Ruby at February 29th, 2012.
3 Comments
Tagged with
optimize,
performance,
Rails,
Ruby. Written by:
stjernstrom
Note to self.
When deploying my RubyOnRails applications with Capistrano and I get errors like this one
1 2 3 4 5
| servers: ["app.myserver.com"]
[app.myserver.com] executing command
** [out :: app.myserver.com] sh: bundle: command not found
command finished in 31ms
servers: ["app.myserver.com"] [app.myserver.com] executing command ** [out :: app.myserver.com] sh: bundle: command not found command finished in 31ms |
Capistrano executes the commands in a very basic shell so the $PATH environment are not the same as when you login through SSH.
One way to solve this is by setting PermitUserEnvironment to yes in /etc/sshd_config and then add the correct PATH to ~/.ssh/environment
I just found another way that was much easier
In you config/deploy.rb add the following snippet
1 2 3
| set :default_environment, {
'PATH' => "/opt/ruby-enterprise/bin/:$PATH"
} |
Thats it!
Cheers!
Posted in
Programming,
Rails,
Ruby at June 1st, 2011.
4 Comments
Tagged with
capistrano,
deploy,
Ruby. Written by:
stjernstrom
A reminder for myself how to batch rename files with spaces in bash.
This is how i rename files with space to have underscores instead. DO NOT blame me if this commando erases all your files
I found several examples how to do this when googling but they all failed. Some of them did nothing and some erased half my filenames. SO IF YOU USE THIS, PLEASE TRY IT IN A FOLDER WITHOUT IMPORTANT FILES FIRST.
1
| for f in *' '*; do mv "$f" "`echo $f | sed -e 's/ /_/g'`"; done |
Cheers!
Posted in
Linux,
Note to self,
Operatingsystem at October 20th, 2010.
No Comments
Tagged with
bash,
linux,
Note. Written by:
stjernstrom
I just have to share this funny quote from the nokogiri website (for those of you that does not know 鋸 it’s a reeeeeeeeaaally good and fast HTML, XML, SAX, and Reader parser).
XML is like violence – if it doesn’t solve your problems, you are not using enough of it. – http://nokogiri.org/
Cheers!
Posted in
Programming,
Ruby at April 2nd, 2010.
No Comments
Tagged with
funny,
parser,
quote,
Ruby,
xml. Written by:
stjernstrom
My Sinatra + Apache + Passenger setup did not just run
Deploying a simple Sinatra rack application under Apache and Phusion Passenger turned out not work out of the box for me.
I already had a virtual host so I decided to deploy with passengers sub URI (sub URI documentation).
To make this work you’ll need Apache installed with Phusion Passenger setup (Passenger installation)
This is what I started with
This is my folders for the already existing website.
1 2 3 4
| # Existing homedir
/home/my_web/
# Current webroot
/home/my_web/htdocs |
Creating folders and files for Sinatra
The first thing you want to do is to create folders and files for Sinatra.
1
| mkdir /home/my_web/sinatra |
1 2 3 4 5 6
| cd /home/my_web/sinatra
mkdir tmp
mkdir logs
mkdir public
touch app.rb
touch config.ru |
Create symlink
Create a symbolic link from our current webroot to the new Sinatra app so that apache/passenger can find it.
1
| ln -s /home/my_web/sinatra/public /home/my_web/htdocs/app |
Creating the application
We also need a Sinatra application for this to work so lets fill those files.
File: config.ru
1 2 3 4 5 6 7 8 9 10 11
| require 'app'
set :environment, ENV['RACK_ENV'].to_sym
set :app_file, 'app.rb'
disable :run
log = File.new("logs/sinatra.log", "a")
STDOUT.reopen(log)
STDERR.reopen(log)
run Sinatra::Application |
File: app.rb
1 2 3 4 5 6 7 8 9 10 11
| require 'rubygems'
require 'sinatra'
before do
# Strip the last / from the path
request.env['PATH_INFO'].gsub!(/\/$/, '')
end
get '' do
"Hello world"
end |
Apache configuration
Now we need to setup apache so that it can find our Sinatra app and load it.
The only thing you need to do is add the following line to your existing VirtualHost block:
This line will tell passenger to look into our existing webroot for a symlink thats named app and which points to our rack app. (RackBaseURI documentation)
Virtual host entry
1 2 3 4 5 6 7 8 9 10 11 12
| <VirtualHost *:80>
ServerName www.example.com
ServerAlias example.com
DocumentRoot /home/my_web/htdocs/
RackBaseURI /app
<Directory "/home/my_web/htdocs/">
Order allow,deny
Allow from all
AllowOverride All
</Directory>
</VirtualHost> |
The best part is that you are allowed to specify this option multiple times. So you can easily setup multiple apps under the same virtual host.
Cheers!
Recently I’ve been working a lot with dates and tonight I had a hard time finding information about how to group a model by date when the model only have a timestamp column.
Lets pretend we have a user model with a created_at attribute which is stored as a timestamp.
If we want to plot a simple graph showing signups per date this is the way to extract them:
1
| User.count(:group => "DATE(created_at)") |
Thats all there is to it. From this you will get an OrderedHash containing the date and count of users for each date.
One small thing to remember if you are using PostgreSQL. You will need the DATE() function in any ORDER/SELECT statements because PostgreSQL will only select/order by fields thats in the GROUP BY statement and this is a pretty healthy behavior that many databases (no names here) don’t care about. Think about it. If you are grouping all users by date and use * as selector how would the database know which username or email address to display?
This is what happens if you try to group by created_at without DATE() ->
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| >> User.count(:order => 'created_at DESC', :group => ["DATE(created_at)"])
ActiveRecord::StatementInvalid: PGError: ERROR: column "users.created_at" must appear in the GROUP BY clause or be used in an aggregate function
: SELECT count(*) AS count_all, DATE(created_at) AS date_created_at FROM "users" GROUP BY DATE(created_at) ORDER BY created_at DESC
from /tmp/app/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb:212:in `log'
from /tmp/app/vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb:507:in `execute'
from /tmp/app/vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb:985:in `select_raw'
from /tmp/app/vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb:972:in `select'
from /tmp/app/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb:7:in `select_all_without_query_cache'
from /tmp/app/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb:62:in `select_all'
from /tmp/app/vendor/rails/activerecord/lib/active_record/calculations.rb:255:in `execute_grouped_calculation'
from /tmp/app/vendor/rails/activerecord/lib/active_record/calculations.rb:132:in `calculate'
from /tmp/app/vendor/rails/activerecord/lib/active_record/calculations.rb:130:in `catch'
from /tmp/app/vendor/rails/activerecord/lib/active_record/calculations.rb:130:in `calculate'
from /tmp/app/vendor/rails/activerecord/lib/active_record/calculations.rb:48:in `count'
from (irb):18 |
And this is the right way to do it:
1 2
| >> User.count(:order => 'DATE(created_at) DESC', :group => ["DATE(created_at)"])
=> #<OrderedHash {"2009-10-14"=>22, "2009-10-25"=>4, "2009-11-04"=>8, "2009-10-15"=>9, "2009-10-26"=>16, "2009-11-05"=>9, "2009-10-16"=>193, "2009-10-27"=>14, "2009-11-06"=>9, "2009-10-17"=>49, "2009-10-28"=>15, "2009-11-07"=>6, "2009-10-18"=>36, "2009-10-29"=>8, "2009-10-19"=>116, "2009-10-30"=>15> |
As you may notice the Hash does not look ordered. But if you loop over it you will get them in order:
1 2 3 4 5 6 7 8 9 10 11 12
| >> User.count(:order => 'DATE(created_at) DESC', :group => ["DATE(created_at)"]).each {|u| puts "#{u[0]} -> #{u[1]}" }
2009-11-07 -> 6
2009-11-06 -> 9
2009-11-05 -> 9
2009-11-04 -> 8
2009-11-03 -> 14
2009-11-02 -> 20
2009-11-01 -> 10
2009-10-31 -> 6
2009-10-30 -> 15
2009-10-29 -> 8
.. |
And thats how you group a timestamp field with just its date part.
Cheers!
A couple of days ago my Terminal.app (console) got a really annoying feature. When launching the console or when I created a new tab it got stuck for about 5-10 seconds before I got my prompt.
If you are like me and are spending most of your time in Terminal.app you understand how annoying this is/was.
I tried to rename .profile, .inputrc and evey other startup script I had in my home folder but the problem did not go away.
Then I found an OSX user which had his Terminal crash when started. He solved his problem by cleaning up some OSX systemlogs. So I thought I try the same trick.
The logfiles which he removed where the asl files under /private/var/log/asl/
I read about them here: http://macosx.com/tech-support/can-i-deleteasl-log/24223.html
But I figured I’d just remove them all
1
| sudo rm -rf /private/var/log/asl/* |
When all asl files where removed my Terminal went back to normal again and I am sooooooo relieved.
This worked for me BUT I do not recommend you to remove anything if you do not know what you are doing!!!
Cheers!