Initial Ubuntu 8.04 Linux Setup 1
After grabbing and installing Ubuntu 8.04 I then had to put together and setup the baby, luckily I wrote down most of everything I did in case I’d have to do it again and to help out you guys.
What follows are my findings and what I did to fix them. The machine I used is an HP Pavillion dv2000 model dv2742 special edition. It’s got a built-in intel graphics card, 3gb memory, sata 250gb drive, wifi, bluetooth and an intel dual core 2 processor.
I installed the o/s using the 64-bit edition of Ubuntu 8.04 Hardy Heron, all what you see below are workable settings which provided the right setup; hope they help your situation if you go down this route.
Update System
First port of call, check for any new updates post-install,
sudo aptitude update
sudo aptitude upgrade
Dependencies / Software / Setup
Next, install Ruby, FlashPlayer, GCC Compiler, MySQL, JAVA, SqlLite,
sudo aptitude install mysql-server flashplugin-nonfree ruby-full libsqlite3-dev build-essential libmysqlclient15-dev sun-java6-jdk
Volume Mixer,
sudo aptitude install gnome-alsamixer
ImageMagick,
sudo aptitude install imagemagick
Ruby Gem Handler
I could get GEM from the repositories but because with each new update it breaks away from the in-built Linux installer it’s best to install it from source,
wget http://rubyforge.org/frs/download.php/34638/rubygems-1.1.0.tgz
tar xzvf rubygems-1.1.0.tgz
cd rubygems-1.1.0
sudo ruby setup.rb
sudo ln -s /usr/bin/gem1.8 /usr/bin/gem
Had problems updating the GEM system initally, so logged in as root to finish it off,
su root
sudo gem update --system
Now when you type gem –version you should see GEM ready to roll,
Gem Libraries
The slow bit, ran this as root just to make sure it worked,
gem install rails
gem install rake
gem install mongrel
gem install mongrel_cluster
gem install thin
gem install capistrano
gem install mysql
gem install termios
gem install sqlite3-ruby
gem install mini_magick
VLC + GIT
Next VLC to play videos,
sudo aptitude install vlc
Transmission for torrents, most important bit,
sudo aptitude install transmission
And GIT to handle code versioning,
sudo aptitude install git-core
Firefox + MS Fonts
Next I need Firebug for Firefox 3. Ubuntu 8.04 comes with Firefox 3 beta 5, the one available thru Tools / Add-ons won’t work with it; but thankfully it’s in the repositories
sudo aptitude install firebug
And you’ll probably need Microsoft Fonts later down the line,
sudo aptitude install msttcorefonts
Pimp GEDIT
The default Gnome Text Editor Isn’t bad but let’s add some extra’s to really kick it in gear,
sudo aptitude install gedit-plugins
And tweak it,
wget http://robzon.kapati.net/rails/rhtml.lang && sudo mv rhtml.lang /usr/share/gtksourceview-2.0/language-specs/
wget http://robzon.kapati.net/rails/rails.xml && sudo mv rails.xml /usr/share/mime/packages
sudo update-mime-database /usr/share/mime
Follow the guide here to get the TextMate look,
Now when you open rails source files they’ll actually look right, thanks Grigio.
PostGreSql + Thunderbird
Pretty easy to install the most powerful db system, and the better email handler
sudo aptitude install postgresql thunderbird
Wine for Windows
Thanks to Google for their support the Wine project is going great, to get Windows software running natively on your machine,
First add the key,
wget -q http://wine.budgetdedicated.com/apt/387EE263.gpg -O- | sudo apt-key add -
Then add the repository to your default repository list,
sudo wget http://wine.budgetdedicated.com/apt/sources.list.d/hardy.list -O /etc/apt/sources.list.d/winehq.list
And finally install it,
sudo apt-get install wine
Effects
To enable compiz effects make sure Appearance / Visual Effects is set to ‘Extra’, then install the Advanced Effects Manager,
sudo aptitude install compizconfig-settings-manager
This will give you access to the 3d cube, skydome effect and a host of other cool addons.
My desktop dpi is set to 100dpi, fonts set to ‘Bitstream Vera Sans Roman 8pt’, with ‘Bitstream Vera Sans Bold 8pt’ for Windows Title; and ‘Liberation Mono 8pt’ for fixed width font. Using subpixel smoothing for LCD.
Sound
For my laptop (hp pavillion dv2000 / dv2742se model), i had to use a different sound mixer to make sure the quickplay volume and mute buttons talked to the sound system.
So from the top menu bar, System / Preferences / Sounds, then set the Default Mixer Tracks hander device to: Conexant CX20561 (hermosa) (oss mixer).
Cleanup
To get any temp files carried on from the install, clean with,
sudo aptitude clean
Job done, however I had a problem with Hibernate & Suspend which was lucky fixed with some advice from here
Record Grouping
Example to go thru your User model and return all the signups by month / year, doing conditionals on them and grouping,
@users = User.find(
:all,
:select => "MONTH(created_at) as month, YEAR(created_at) as year, COUNT(*) AS records",
:conditions => ["admin = 0'"],
:group => "year, month")
You can use this in your view like,
<% for @user in @users %>
<%=@user.month%>
<%=@user.year%>
<%=@user.records%> signups
<% end %>
Ruby date_select conversion 2
Had a bit of a pain with Ruby’s handling of Date/Time values coming from a Date_Select form element, managed to solve it though.
The problem was that in my form…
<%=date_select(:date,'',:start_year => 1950,:include_blank => false, :default => { :year => '1970' })%>
…the value I got back from the submitted field,
params[:date]
became…
'(3i)4(1i)1953(2i)5'
Bit of a mess, obviously I was expecting something a little more legible like 1953-5-4 (yyyy-mm-dd), so I bashed my head against a brick wall trying to work it out, I could have made my life easier with some select_date blocks but I’m a guy how likes to ask ‘why’ so I perceviered.
Turns out in my travels you can do this to break it into a usable DateTime object..
Time.mktime(params[:date]['(1i)'],params[:date]['(2i)'],params[:date]['(3i)'])
Which will return something much more legible…
Sun May 19 00:00:00 +0100 1968
Or whip it into a method to do exactly what you want…
def convert_date(obj)
return "#{obj['(1i)']}-#{obj['(2i)']}-#{obj['(2i)']}"
end
<%=convert_date(params[:date])%>
But wait, it doesn’t end there, you could use Date.new or Date.civil to parse it into a real date object like…
def convert_date(obj)
return Date.new(obj['(1i)'].to_i,obj['(2i)'].to_i,obj['(3i)'].to_i)
end
Which will return…
1967-03-19
Much nicer, just remember to use .to_i otherwise you’ll get…
comparison of String with 0 failed
Enjoy!
Rails Sessions

To make a truly intelligent web application your gonna sooner or later have to play around with Sessions, which is basically a Cookie’s big brother.
Store in DB
Now Rails initally will store all it’s session data in a text file within the /tmp/sessions directory of your rails app, which is usually ok, but if you’re gonna build a production-ready app you’re gonna want to up the ante somewhat and store them in your DB.
This is simply done by opening up your environment.rb file and un-commenting the following line…
(within /config/environment.rb)
config.action_controller.session_store = :active_record_storeThen in the command-line generate a RAKE DB migration for your Session objects (so they’re stored in your db from now on).
rake db:sessions:create
rake db:migrateBingo, you now have a table within your database hooked up and ready to store your session data perfectly.
Storing Session Objects
Now that you’ve got your DB storing your session data, why don’t we start creating some session objects.
This is done by…
session[:order] = 'ASC'Here, we’ve simply created a new session object, storing in it a text value of ‘ASC’; cool eh?
We can then check to see if our session is empty via…
if session[:order].blank?
..do stuff..So if our session object contains nothing we can initialise it correctly.
Common Gotcha
Now one of the good things with switching sessions over to your db is that it’ll secure your app a little bit better and your performance will improve.
Plus if your building your app on your dev machine, then transfer it to your live box, but can’t find a reason why your sessions don’t work there it’s usually down to file permissions for the session file; by switching sessions over to a db you remove any future problem of this.
Good eh,
Rails : Exception Catching
Global Error Catching
To handle errors globally in your application, add..
(within application.rb)
def rescue_action_in_public(exception)
render :text => "<html><body><p>
There was a global error processing your request.</p>
<!-- #{exception} --></body></html>"
end
def local_request?
false
endThe final def def local_request? tells rails that it should act the same way in development mode.
Local Error Catching
To catch errors locally within your form submits do…
def update
return unless request.post?
begin
User.update(self.current_user.id, params[:user])
render :action => 'success'
rescue ActiveRecord::RecordInvalid
flash[:notice] = "Sorry, your profile was not saved"
render :action => 'profile'
rescue
flash[:notice] = "Sorry, something went wrong"
render :action => 'profile'
end
endSimple process, here we’re basically saying if the user has submitted form data (done a POST), then process the code; if not redirect back to the sending page.
If yes then update the User object relevant to the specific user record (found by the id), updating the record with the parameters from the form. Save the record and render the ‘success’ page.
If we get a problem with saving the record (activerecord), display a message and goto the ‘profile’ page.
If we get some other error, display the second message and goto the ‘profile’ page.
Notify Me of Errors via Email
On top of this you can enhance it with flash messages and send off an email with the error code, here’s one such way.
(in application.rb)
protected
def log_error(exception)
super(exception)
begin
Alert.deliver_errormail(
exception,
clean_backtrace(exception),
@session.instance_variable_get("@data"),
@params,
@request.env)
rescue => e
logger.error(e)
end
endAdding this makes it send error emails in development mode..
def local_request?
false
endNow create an Mailer object with…
script/generate mailer AlertAnd put this code in your generated alert.rb file
class Alert < ActionMailer::Base
def errormail(exception, trace, session, params, env, sent_on = Time.now)
content_type "text/html"
@recipients = 'john@gmail.com'
@from = 'admin@mysite.com'
@subject = "[Error] exception in #{env['REQUEST_URI']}"
@sent_on = sent_on
@body["exception"] = exception
@body["trace"] = trace
@body["session"] = session
@body["params"] = params
@body["env"] = env
end
endAnd create a appropriate alert/errormail.rhtml file in your view for the formatted error email…
<style>
<!--
* { font-size: 9pt; font-family: verdana, helvetica, arial, sans-serif; line-height: 1.7em; }
p { margin: 0 }
-->
</style>
<h2>Error report from <%= Time.now %></h2>
<table border="0">
<tr><td>Message</td><td><%= @exception.message %></td></tr>
<tr><td>Location</td><td><%= @env['REQUEST_URI'] %></td></tr>
<tr><td>Action</td><td><%= @params.delete('action') %></td></tr>
<tr><td>Controller</td><td><%= @params.delete('controller') %></td></tr>
<tr><td>Query</td><td><%= @env['QUERY_STRING'] %></td></tr>
<tr><td>Method</td><td><%= @env['REQUEST_METHOD'] %></td></tr>
<tr><td>SSL</td><td><%= @env['SERVER_PORT'].to_i == 443 ? "true" : "false" %></td></tr>
<tr><td>Agent</td><td><%= @env['HTTP_USER_AGENT'] %></td></tr>
<% if @session['user'] -%>
<tr><td>User id</td><td><%= @session['user'].id %></td></tr>
<tr><td>User name</td><td><%= @session['user'].name %></td></tr>
<tr><td>User email</td><td><%= @session['user'].email %></td></tr>
<tr><td>Registered</td><td><%= @session['user'].created_at %></td></tr>
<% end -%>
</table>
<h3>Backtrace</h3>
<div><%= @trace.to_a.join("</p>\n<p>") -%></div>
<h3>Params</h3>
<hr/>
<% for key, val in @params -%>
<p><b><%= key %></b></p>
<p><%= val.to_yaml.to_a.join("</p>\n<p> ") %></p>
<% end if @params -%>
<h3>Session</h3>
<hr/>
<% for key, val in @session -%>
<p><b><%= key %></b></p>
<p><%= val.to_yaml.to_a.join("</p>\n<p> ") %></p>
<% end if @session -%>
<h3>Environment</h3>
<hr/>
<table border="0">
<% for key, val in @env -%>
<tr>
<td>
<small><b><%= key %></b></small>
</td>
<td>
<small><%= val %></small>
</td>
</tr>
<% end if @env -%>
</table>Now whenever an error happens you’ll get an email about it, good for the production environment.
Setup the Emailer
Remember to setup the emailer otherwise no emails will be sent.
By adding this to your environments/production.rb
config.action_mailer.raise_delivery_errors = true
ActionMailer::Base.delivery_method = :sendmail
ActionMailer::Base.sendmail_settings = {
:location => '/usr/sbin/sendmail',
:arguments => '-i -t'
}Or more detailed,
Setup a DNS MX Record so you don’t get blacklisted!
A further note, remember to add an MX record for the domain your using otherwise your site will be blacklisted by anti-spam sites.
An MX record basically tells other sites where they should send emails to, it’s like saying where the postman should deliver incoming letters.
Now if your only sending emails you shouldn’t need this but as a previous commenter noted, most anti-spam sites blacklist you if your sending and don’t have one; regardless of whether you want the site to receive emails or not. Hence you’ve got to include one.
A simple example is…
type: MX
name: mysite.com
data: ASPMX.L.GOOGLE.COM.
auxilary info: 1Now ok, this is actually telling anti-spammers your using Google Applications to handle your email (which isn’t strictly true) but at least it get’s them off your back until you setup your own full-blown POSTFIX mail server.
Which is something I’m working on writing an article for.
Expect that in a future posting.




