Powered By BlogNow - Get Your Free Blog
Blog Rating:
Stars
RateBar
(5 out of 5 as rated by 1 users)

I have moved!

My new blog is at lindsaar.net

All the old content will stay here though. But check out the new blog

¿ 7/11/2007 - Getting ImageScience and ImageMagick working on OpenBSD

This took a bit of work to make it go right... but here are the basic steps:

   1. Install GNU Make

      You need this to get Free Image compiled later on.  Dont worry, it is fine.

      Go get make-3.81  I can't remember the URL... you should be able to find it easy enough.

      Un tar it, cd into the directory, type "make" then "make install" and you are done.

      You could also move the original make in /usr/bin/make to /usr/bin/make.old and link your GNU make as /usr/bin/make if you want... but that's up to you.

   2. Install Image Magick

      I got the no x11 version as none of my servers use X11.  You can get it from the packages directory at OpenBSD.org.

      You need this one for no x11 support.

      Just down load it and do a:

      "pkg_add ImageMagick-6.3.2.1-no_x11.tgz"

   3. Install the other required package dependencies

      From memory, you need the following packages installed as well:

      ghostscript-8.54p0-no_x11.tgz
      ghostscript-fonts-8.11.tgz
      jasper-1.701.0p1.tgz
      jbigkit-1.6p1.tgz
      lcms-1.15.tgz
      netpbm-10.26.38.tgz
      tiff-3.8.2p0.tgz
      transfig-3.2.4p0.tgz

      Get them all from the same site as the Image Magick one.

   4. Install FreeImage

      Here you need to hack a bit.

      Go to the FreeImage website and download FreeImage.  Here is the link.

      Unzip it in your folder of choice (I use /usr/local/src/)

      $ unzip FreeImage393.zip

      Change into the FreeImage directory and rename the Makefile.gnu to Makefile:

      $ mv Makefile Makefile.orig
      $ mv Makefile.gnu Makefile

      Then modify the install script to replace group "root" with group "wheel"

      Change this:

      install:
              install -m 644 -o root -g root $(HEADER) $(INCDIR)
              install -m 644 -o root -g root $(STATICLIB) $(INSTALLDIR)
              install -m 755 -o root -g root $(SHAREDLIB) $(INSTALLDIR)
              ln -sf $(SHAREDLIB) $(INSTALLDIR)/$(VERLIBNAME)
              ln -sf $(VERLIBNAME) $(INSTALLDIR)/$(LIBNAME)
              ldconfig

      To this:

      install:
              install -m 644 -o root -g wheel $(HEADER) $(INCDIR)
              install -m 644 -o root -g wheel $(STATICLIB) $(INSTALLDIR)
              install -m 755 -o root -g wheel $(SHAREDLIB) $(INSTALLDIR)
              ln -sf $(SHAREDLIB) $(INSTALLDIR)/$(VERLIBNAME)
              ln -sf $(VERLIBNAME) $(INSTALLDIR)/$(LIBNAME)
              ldconfig

      Then save this and type "make" (if you have done the linking thing above moving the original make away to somewhere else).

      It will go off for a while and make the library.  When it is done, type "make install".

   5. Install Image Science

      gem install image_science   (nuf said)

   6. TEST IT!

      $ irb
      irb(main):001:0> require 'rubygems'
      => true
      irb(main):002:0> require 'image_science'
      => true
      irb(main):003:0>

And you're done!

Hope that helps someone else and reminds me how to do it next time! :)

blogLater

Mikel

Comments (0) :: Post A Comment! :: Permanent Link

¿ 6/11/2007 - No to Microsoft's XML implementation

This is something every one should sign.

They are up to 61,000 signatures now... we need to get this to a couple of million.

http://www.noooxml.org/petition

Basically, there is already an open document format.  We don't need two formats.  Microsoft tried to get their format ratified, it got out voted... that is good.  They are still trying, that is bad.

We need to say "NO, ONE OPEN FORMAT IS ENOUGH"

Go and sign it...

Now...

Seriously...

I'll still be here when you get back :)

blogLater

Mikel
Comments (0) :: Post A Comment! :: Permanent Link

¿ 22/10/2007 - Fix for TMail to handle MS Outlook MIME Emails

I ran into this bug yesterday.

I use the TMail library, it handles email very well.  However, MS outlook express sets the Content-Type boundary= value to an illegal value.  Per RFC 2045 you can't have ? or / or = in the boundary text field.  MS Outlook uses "=" which then breaks TMail trying to read it.

What then happens is when you do a tmail_object.to_s it does not include the content-type field and your email looks like really bad plain text with the MIME parts treated as plain text, not MIME parts.

Per the RFC, if you want to use these illegal characters, you need to quote the field.

So this fix just puts in a "clean_bad_boundary" method to add quote marks around any boundary field that contains illegal characters.  Simple and it works quickly.

You can download the file from here: TMail Patch.

It is a diff file which changes two files in the TMail 0.10.8 branch (the testheader file and the header file) and includes failing tests which then pass when you apply the diff to header.rb.

Enjoy.

blogLater

Mikel
Comments (0) :: Post A Comment! :: Permanent Link

¿ 21/10/2007 - Self Refferential Associations with Ruby on Rails, active_scaffold with acts_as_nested_set

Today I had to get an active_scaffold based admin interface working with a model that was a nested set.

Active Scaffold has a "config.nested.add_link" option, but this obviously didn't work just "out of the box" as a nested set does not have any Active Record associations as such.  It has children and parents, but these are not found through "has_many" and "belongs_to".

The solution was actually quite simple.  Use the Active Scaffold reverse association method and define the association.

So i thought I would write it up here.

First, you have a page model.  A page (like a web page) belongs in a tree.  A page has a parent and has many children.  I am using this as an interface to a website, the root is the home page, which has many links, all of which are children to the root page.  Those children can also have children which are then sub pages to that subject.

So we have a page migration and model that looks basically like this:

Migration:

class CreatePages < ActiveRecord::Migration
  def self.up
    create_table :pages do |t|
      t.column :title, :string
      t.column :parent_id, :integer
      t.column :rgt, :integer
      t.column :lft, :integer
    end
  end

  def self.down
    drop_table :pages
  end
end

Model:

class Page < ActiveRecord::Base
  acts_as_nested_set
end


To add the active scaffold work to this, you have to define a self-refferential association between a Page and it's children.  As the child is also a page, you use the foreign_key and class_name options to the belongs to and has many.

So this model code becomes:

class Page < ActiveRecord::Base
  acts_as_nested_set
 
  belongs_to :parent,
             :foreign_key => :parent_id,
             :class_name => "Page"
  has_many   :children,
             :foreign_key => :parent_id,
             :class_name => "Page"
end

As we already have a "parent_id" as part of the nested set, we can conveniently use this for the association foreign key.

Then, in the controller we can do:

class PagesController < ApplicationController

  active_scaffold :page do |config|
    config.columns[:children].association.reverse = :parent
    config.nested.add_link("Show Children", [:children])
  end

end

end

The first line in the config tells Active Scaffold explicitly what the reverse association is.  This is needed as the self referrential nested set doesn't just work straight away as it is a bit of a unique case.

The second line simply provides a link on each record to allow you to show it's children.

I hope that helps someone else.  Not hard, but will save you the 15 minutes putting the code together.

blogLater


Mikel
Comments (1) :: Post A Comment! :: Permanent Link

¿ 6/5/2008 - Thanks Much for a great post

Posted by Anonymous
This saved me a ton of time
Permanent Link

¿ 16/10/2007 - RSpec, Rails, Ruby and Textmate File Associations

I have been having a problem with Textmate.

Basically, when you are using Textmate in Rails with RSpec, you have to keep telling textmate which is Rails and which files are RSpec.  Problem is, they both have the same extension (.rb) so you run into problems and constantly have to change bundle selections to make it work.

The handling?

Well, I headed over to the #textmate channel on freenode, and asked.  Mr Allan Odgaard himself (the author) helped me out... and solved the problem!

Make the default scope Rails and then modify the Rails and Ruby language definitions to remove .rb from Ruby and add .rb to Rails.

(obviously you can change this back if you need to)

If you have a similar problem, head over to his blog to get the solution with the full explanation of why it is so.


blogLater

Mikel
Comments (0) :: Post A Comment! :: Permanent Link

¿ 13/10/2007 - CRC Cards and Object Oriented Design

Found this today, Class-Responsibility-Collaborator Cards....

Basically... you have your overall problem in getting a program done... you want to create it in an Object Oriented Way... so what you do is you make CRC cards for each class in your proposed program.

On each card is the name of the class, what it is responsible for and what it collaborates with.

This works great with RSpec!

And Rails?!  Perfect match!

I am going to implement it as part of the site i am doing now.

blogLater!

Mikel
Comments (1) :: Post A Comment! :: Permanent Link

¿ 25/11/2007 - Related Item

Posted by Grahame
Another great resource for helping in design in this: http://www.softwarestencils.com/uml/index.html - It's a UML template for Visio. The advantage it has over the templates that come with Visio is that this one lets you do "free-form" UML so you aren't forced into following the strict rules if all you want is to do a UML "sketch". I use it all the time.
Permanent Link

¿ 5/10/2007 - Samba with OpenLDAP - the absolute howto guide

Hmm... seems to be my configuration day.

If you read my post a few days ago about getting Samba to work, then you might also be interested in some of these.  I know I was.

I was setting up a Samba server backing up against an OpenLDAP server backend for authentication and definition of the users.

It took a bit of work... but in the end... I followed one example EXACTLY... got THAT working, and then went onto the next example to get THAT working.

Honestly, it is the best way to do it.

If you are just starting and want to get Samba working with OpenLDAP, do the following:

The Samba Guide - Chapter 5 - Making Happy Users.

This guide is based on Linux, it also works for FreeBSD (just take out any reference to shadow accounts in the PAM and NSS stuff).

I did the whole guide and got the server running... then I started doing some other stuff and now I have a nicely configured running server.

Anyway... blogLater

Mikel
Comments (0) :: Post A Comment! :: Permanent Link

¿ 5/10/2007 - How to configure a CISCO router on ADSL etc

Having setup a few ciscos in my time... sometimes you just need to remember "Just how did I handle that config again?"

Well... great website for you (and me) is the Configuration Examples and TechNotes page from CISCO.

Go have a read next time you need to set up a router... you will save yourself hours of fun...

blogLater

Mikel
Comments (0) :: Post A Comment! :: Permanent Link

¿ 4/10/2007 - From nothing to Something. Design Driven Development with Ruby on Rails

I have to make a new website for an organization.

It is a fairly simple site, basic information, but they want the ability to accept payments and track payments, update stories etc.

This got me thinking.

Having built some good web applications in rails, I wondered what it would be like to build a website in rails?

Note... I think the distinction between a website and a webapp is disappearing, anyone just building a static webpage really is not going to get anywhere in terms of interest from the public.  Sure, it will answer questions, and if this is all you need, then fine.  But if you want to engage your public, then you need something more.

But how do you make an organizational website without going through the entire "web app" thing?

The web is full of how to make a blog and how to list products against categories, but how do you actually cross the line between being a ruby on rails programmer to a website designer?

Well, that is what the next series of posts is going to cover.

I am going to create a website from the bottom up, out of whole cloth and create it all using ruby on rails with Rspec every step of the way.

The end result will be a running website that fullfills the purpose that is needed.

And it might also help someone out there with a similar problem!

I find (per the technology of study and management that I have learnt from Hubbard Management Technology) it is good to have a battle plan.  A series of doable steps that get you from where you are to where you want to go.  The main 3 targets below are part of the Hubbard management technology.

This plan doesn't have to be concrete, it can change in the "heat of battle", but it is your overall set of things to do to get the whole job done.

So to do this web site, the following would be my basic battle plan:

  1. Get a communication going
    1. Establish a communication line with the person who wants the site.
    2. Make sure they know who you are, what you do, what you have done. Get a feel for them as well
  2. Find out what is needed and wanted
    1. TALK WITH YOUR CLIENT
    2. Draw, look at pervious websites together, look at websites they like, do they want professional and slick, or fun and friendly?  What is the mood they want to convey?  Safe and reliable, or cutting edge and in your face?  Get the feel.
    3. Get lists of things they want on the site
  3. Do, Produce or Present it
    1. Wireframe design and work out what is needed on the pages
    2. Basic look and feel design, how is the site going to hang together
    3. Getting the pages up by using Design Driven Development
    4. Getting the look and feel working (Lorem Ipsum stage)
    5. Coding the backend to the site using Behaviour Driven Development (BDD)
    6. Coding the interactions with other services (payment gateways etc) using BDD
    7. Populating the site with data
    8. Staging the server and inhouse testing
    9. Putting the site online!
See... how hard could that be?

This project / tutorial is going to start at the "Do, Produce or Present It" stage of the battle plan.  I am going to assume you know what is needed and wanted and you have your communication lines in with your client (or maybe you are doing this for yourself).  Regardless of if it is a client or yourself, be sure to do steps one and two first before step three otherwise you will find yourself lost in a hurry.

Anyway, I'm going to head off and get the first target of step three done, and I'll blog about it to you later.

Mikel
Comments (2) :: Post A Comment! :: Permanent Link

¿ 5/10/2007 - Rails?

Posted by Anonymous
You might want to consider using something lighter-weight, if it's mostly static content. Like http://staticmatic.rubyforge.org/


Permanent Link

¿ 5/10/2007 - Staticmatic

Posted by mikel
Thanks for the pointer. Looks interesting... but I think for this project I am going to stick with Rails.

I guess it comes down to what is static and what is dynamic and where do you draw the line.

They want the option to update sections of text, small blog on the page, login of members, and the payment gateway. Some of this requires some sort of DB backend.

The previous site is in PHP, and while I made it in PHP and it looks OK, I find I am repeating myself a lot and don't really need to.

But we will see how it goes!
Permanent Link

¿ 29/9/2007 - 640Gb Solid State "Hard Drive"

Well, it has finally happened, a hard "drive" that will just basically whipe hard drives out of existence.

Except this isn't a hard drive, it is a PCI Card, and it doesn't do 100 read writes per second, it does 100,000.

That is just amazing, but Hard Drives have been the bottle neck ever since I bought my first 10Mb HDD in the early 80's, it's about time there was a radical change.

You can go read about it here.

blogLater,

Mikel
Comments (0) :: Post A Comment! :: Permanent Link

¿ 26/9/2007 - How to optimize a rails site... the easy way.

OK.

I have a dog of an app.  34 second page loads not uncommon...

Yes... you hear right.  Half a MINUTE to load the page.

And no, it is not complex, no, it is not even super heavy on the database side.  It is just a long neglected, unoptimized, admin app that I use for a variety of things that was always at the bottom of my list of things to do.

So i thought I would take a few moments and speed it up.

Result:

Before SIMPLE optimization - 34 seconds

After SIMPLE optimization - 1.8 seconds.

Not a bad improvement, considering I didn't change a line of code in my app.

The trick?

Easy, make your javascript smaller, reduce the number of scripts and compress your content. Ok... this is how in detail.

First, go get Firefox or BonEcho and install the YSlow plugin from http://developer.yahoo.com/yslow/  This will give you a option at the bottom of your browser and can tell you how long it takes to download your page, go check it out and use it.  This gives you pretty much all the hints you need to speed up your page.

Then, for me, the biggest gain is reducing the number of script files you call.  This is becuase a web browser will only download 2 items from any one server at a time.  So, say you have 5-6 javascript files in the top of your application.rhtml file in /views/layouts/, This is not hard to do, especially if you include the default javascript files with the rails helper.

Well... if you have 6, this means that the browser downloads two, then the next two, then the next two.  While it is doing this, nothing on your page renders to the end user and all you get is a blank browser window.

The handling?

Well, combine it all into one file.

You can do this simply, from the command line, do the following:

# cat prototype.js >> alltogether.js
# cat next.js >> alltogether.js
# cat effects.js >> alltogether.js
# cat dragdrop.js >> alltogether.js
# cat another.js >> alltogether.js


Then go into your application.rhtml file and take out all your javascript script tags and replace them with:

script src="/javascripts/alltogether.js?1" type="text/javascript"

The ?1 on the end is the version number.

Now try loading your page, you will see an instant increase in speed.

Next, we want to strip out of that combined file all the comments and extra white space.  A nice easy rubyfied program for this is at:

http://www.crockford.com/javascript/jsmin.rb


Download this into a file called jsmin.rb.

Then, run the following:

# ruby jsmin.rb < alltogether.js > combined.js


Now, move this combined.js filed into your public/javascripts directory and replace out the script line to read:

script src="/javascripts/combined.js?1" type = "text/javascript"


Now, another reload, and it should be faster again.

Then, I went into my apache config file and added in
ExpiresDefault "access plus 1 month"

You put this inside the < Directory "/path/to/rails/public/" > < / Directory > tags

You can make this more than a month, but for me, a month is fine.

Anyway, with that in place, my load time droped from 34 seconds to 1.8 seconds.

Not too shabby.

blogLater.

Mikel
Comments (0) :: Post A Comment! :: Permanent Link

¿ 24/9/2007 - Creating home and profile directories automatically in SAMBA and unix

I was playing with samba, unix and LDAP over the past day or two.

Found a situation where I had to create home directories and profile directories for users when they first log in (due to the way the accounts were being created).

Found a solution in samba's pre exec scripts.

Note, this is on a computer with no internet connection, so I would not recommend using this without really knowing what you are doing if this system is on the internet.

in smb.conf:

[home]
root preexec =
/usr/local/scripts/makehome.sh %u

[profile]
root preexec = /usr/local/scripts/makeprofile.sh %u


Then, those two scripts:

[raasdnil@server ~]# cat /usr/local/scripts/makehome.sh
#!/bin/sh
if [ ! -d '/home/$1' ]; then
        mkdir '/home/$1';
        chown -R $1:user '/home/$1';
fi

[
raasdnil@server ~]# cat /usr/local/scripts/makeprofile.sh
#!/bin/sh
if [ ! -d "/usr/samba-shares/profiles/$1" ]; then
        mkdir "/usr/samba-shares/profiles/$1";
        chown -R $1:user "/usr/samba-shares/profiles/$1";
fi

What this does is when the user logs on, it checks to see if a directory exists in the right places.  If it does not, it makes it and then owns it to the user.

Possible problems with this would be passing ../../somedir to get out of the current directory, but the end result would be some directory on the file server read writable for the user (the script exists if the file exists) so there is little chance of damage on this front.

A good idea would be to strip out any illegal characters like ../ from the input just in case.  For a later time.

blogLater

Mikel
Comments (0) :: Post A Comment! :: Permanent Link

¿ 1/9/2007 - Installing OpenBSD via Serial Console on a HP Proliant Blade Server Blade

I had the chance to play with a blade server this weekend.  Specifically a HP Proliant with 10 BL10e G2 blades in it.

I decided to install OpenBSD.  Also decided to do it via the administration console (which gives you a serial console to each blade).

Per the OpenBSD website, says you can install OpenBSD via the console, so why not give it a shot?  Keyboards, Floppy Drives and Screens are for loosers :)

Besides, there is a practical side to this... if the blade needs reinstalling while it is in a server room rack at a remote location, then you can do it from your office :)

Ok, so here are the basic steps:

  1. Login to the admin module
  2. Get the MAC address of the NIC #1 on the blade you want to install
  3. Set up a DHCP setting which includes the MAC address and the pxeboot filename per the OpenBSD website
  4. Extract the kernal from an OpenBSD boot floppy (see below)
  5. Make a custom boot.conf to fix the port and speed to com1 and 115200 respectively (see below)
  6. Copy the bsd file and etc directoy of your custom floppy image to /tftpboot/
  7. Boot your blade,
  8. Connect to your blade
  9. Select PXE boot (ESC-SHIFT-2 at the appropriate prompt)
  10. Type "floppy41.fs" or whatever name you called your floppy
Now... the details:

This is what you put in your boot conf file:

set tty com0
stty com0 115200

The first line redirects all output to the com0 port (which is the one you connect to via the Admin module) the second line sets the speed.  This is needed because OpenBSD defaults to 9600 and the  HP administrative console connects to the blade at 115200.  If you don't do this, then when you boot, it will look like it has frozen just after loading the image.  Sometimes it will give you ### other times nothing.

The lines in the dhcpd.conf file look something like:

host blade {
  hardware ethernet 00:BB:CC:DD:EE:FF;
  fixed-address 10.0.0.2;
  next-server 10.0.0.1;
  filename "pxeboot";
}

The first line says "This config is only to be applied to a computer with the MAC address of
00:BB:CC:DD:EE:FF"

The second line says "Give this computer the IP address
10.0.0.2" (useful for restricting access to your TFTP server).

The third line says "Once you give the card an IP address, tell it the TFTP server IP address is 10.0.0.1"

The third line says "When it connects, download to the NIC the pxeboot file"  You can find this file in /usr/mdec/pxeboot and can just copy it as is to /tftpboot

Steps to do the floppy are (following taken and modified from OnLamp)

Get a floppy from the OpenBSD site.

Then:

# vnconfig /dev/svnd0c /tmp/floppy41.fs
# mount /dev/svnd0c /mnt
# cp /mnt/bsd /tftpboot/
# umount /mnt
# vnconfig -u /dev/svnd0c
# mkdir /tftpboot/etc
# vi /tftpboot/etc/boot.conf


Then add the two lines from above and save the boot.conf file.

This needs to all go into /tftpboot as OpenBSD's tftpd server is chrooted to /tftpboot by default.

Make sure all your files in /tftpboot are world readable which a chmod -R o+r /tftpboot/*

Good luck!

Mikel
Comments (0) :: Post A Comment! :: Permanent Link

¿ 14/8/2007 - Rails on OpenBSD include file won't include

Ok... this is a stupid one.

In my code, i use the RFC822 email module which defines a constant RFC822 which is a regexp that matches pretty much any email... at least... it matches what RFC822 is meant to match, so, good enough.

However, I named this file RFC822.rb in my /lib directory.

Why?  Looks correct.

Works fine... at least on my mac.

Once I deployed to my OpenBSD box, none of the classes that used RFC822 worked!

The problem is that the mac is case insensitive! So the include command went looking for rfc822.rb (as well files are lower case) and MacOSX served up RFC822.rb as the perfect match.

OpenBSD is a bit more picky in it's file match making and decided that RFC822.rb could go find it's own match as far as it was concerned and so the include failed .

Gotcha #4

blogLater

Mikel
Comments (0) :: Post A Comment! :: Permanent Link

¿ 14/8/2007 - Capistrano and Ruby on Rails on OpenBSD

So, here we are on OpenBSD, got the rails app working, got the Apache talking, and all of this is wrapped up in a chrooted environment.

Life is good.

Now, we just have to set up the Capistrano deployment and we will be fine... no problem I hear you say.

Well, you are mostly right.

Some gotchas (rapidly):

  1. The user that Capistrano uses to ssh in has to have a POSIX shell... that basically means BASH.  So if the account you are using for Capistrano uses TCSH... it ain't gonna werk Caap'n!
  2. You are deploying into a chrooted environment... chrooted... got it?  Repeat after me, ch root ed.  That means... actually... lets get out of this list and i'll explain more fully.
Capistrano does a near little thing when it deploys your app.  It deploys it into a releases directory with a date.

It then makes a symlink from releases/200708BLAH/ to your current directory.  This way, changing versions of your app is as simple as changing the symlink.

But you are in a chrooted environment. 

So looking at the symlink you get something like:

current -> /var/www/rails/appname/releases/20070809BLAH

Which won't work, because you are chrooted into /var/www and so there is no /var/www there is just /

A simple solution is to make a var directory in your /var/www directory, and then make a symlink like so:

cd /var/www
mkdir var
cd var
ln -s ../ www


Then, when the app follows the symlink to /var/www, it gets put back up to /var/www and then can change down through /var/www without having to actually get to the real /var/www....

Confused? So was I... . end of class.

Of course... it sets up a loop in your directory structure.... I'm welcome to comments on the security implications of this (I can't think of any off hand) but you wouldn't want to run a script that drills down through the directory tree.... as it might take some time..............

blogLater


Mikel
Comments (0) :: Post A Comment! :: Permanent Link

¿ 13/8/2007 - Ruby on Rails in OpenBSD chroot

Was getting OpenBSD working today and ran into a bug.

Specifically, it wouldn't start.  Looking in the development.log I found this offensive error...

No such file or directory - /tmp/mysql.sock

OK, so we can't get to the mysql.socket file...

Good, lets find the socket file.. on my OpenBSD system, this lives in /var/run/mysql/mysql.sock

So... going into database.yml, change this to reflect:

development:
  adapter: mysql
  database: test_development
  socket: /var/run/mysql/mysql.sock
  username: username
  password: password
  host: localhost

Run it all again, still error.. look in the development log, now we find:

No such file or directory - /var/run/mysql/mysql.sock

HUH?!

After thinking about this for a bit, I remember I am running apache in a chroot environment, and of course you wouldn't be able to reach a directory that is outside the chroot environment.  Think about THIS for second and realise, best way?  Don't use a socket and use a TCP/IP port instead...

So the final result:
development:
adapter: mysql
database: test_development
username: username
password: password
host: 127.0.0.1
port: 3306


And voila!

blogLater

Mikel
Comments (1) :: Post A Comment! :: Permanent Link

¿ 25/10/2007 - Using a mysql socket from apache chroot

Posted by Anonymous

I use a socket, you just need to set it up before it can be seen from the chroot jail, here is the startup code in /etc/rc.local

[code]
# Add your local startup actions here.
# Start MySQL server
if [ -x /usr/local/bin/mysqld_safe ] ; then
su -c _mysql root -c '/usr/local/bin/mysqld_safe &' > /dev/null & echo -n ' mysql'

for i in 1 2 3 4 5 6; do
if [ -S /var/run/mysql/mysql.sock ]; then
break
else
sleep 1
echo -n "."
fi
done

# Apache chroot Settings
mkdir -p /var/www/var/run/mysql
sleep 2
ln -f /var/run/mysql/mysql.sock /var/www/var/run/mysql/mysql.sock

fi
[/code]

my script got mangled, since I don't know the formatting rules here, but you get the idea ;)

-Sean

Permanent Link

¿ 25/7/2007 - How to mock a block?

I guess you could just call it dull witted.... but while it might achieve the goal of mocking the block... it wouldn't get your spec passed. And probably is not the Ruby Way.

So, I had to dig and look and hunt and scratch.

After a lot of that, I didn't find the answer....

SO!  I went on the RSpec mailing list and asked, and lo and behold, an answer cometh...

Here is the situation (so you guys can avoid the same problem).

Basically, I wanted to do a look up of the MX record against a domain name to work out if that domain name is a valid address to receive email or not.

Using the Resolv library, I was calling a class method which returned another class instance which then had another class method called on it to get a result.  Complicated?  Only in writing, this is what I was doing:

  Resolv::DNS.open do |dns|
    @mx = dns.getresources(domain_name, Resolv::DNS::Resource::IN::MX)
  end


What I wanted to do is control, in my spec, what value was assigned to @mx.

The solution?  Insanely simple (as most ruby is, just call "and_yields" instead of "and_returns".  So my spec now looks like this:

 @dns = mock(Resolv::DNS)
 Resolv::DNS.should_receive(:open).once.and_yield(@dns)


I hope that helps some other people out there.
Of course, that is only the snippet of the spec, only what you need to get started :)

blogLater

Mikel
Comments (0) :: Post A Comment! :: Permanent Link

¿ 23/7/2007 - To Mock or not To Mock, THAT is the question

describe Mock, "usage" do

  before(:each) do
    @type_of = mock(YouShould, :define => "your mock requirements")
    AMock.should_receive(:requests_for_data).
          with("information you provide").and_return("anything")
  end

  it "should be intuitive" do
    @mocks.should_be easy_to_read
  end
  
  it "should not be reliant on fixtures" do
    @a_good = mock(IsNotReliantOn, :fixtures => "at all")
    @a_good.without_fixtures = "happiness"
  end

  it "should describe what you are doing" do
    @mocks.help("You define your application")
    @mocks.should help_not_hinder_production
  end

end
Comments (0) :: Post A Comment! :: Permanent Link

¿ 22/7/2007 - Reflect on association one liner to check association details

Evgeny asked me about my reflect_on_association post to find out if a one liner could be made to check several association values, that is, not just trusting that the association details would be correct.

You can't do it in a one liner, but this is how to make it as simple and DRY as possible for testing on multiple models.

First off, Class.reflect_on_association returns something akin to a hash, but not a hash.  It actually returns an object of type ActiveRecord::Reflection::AssociationReflection

So, to test this, we need to get the data into a usable form.

This is done through a helper method in spec_helper.rb (if you are using RSpec.

I used this:

  module ActiveRecord
module Reflection
class AssociationReflection
def to_hash
{
:macro => @macro,
:options => @options,
:class_name => @class_name || @name.to_s.singularize.camelize
 }
end
end
end
end


Then, in the spec you are testing, you can do:

  it "should test reflection details" do

association_results = {
:macro => :belongs_to,
:options => {:counter_cache => :true},
:class_name => "Location"
}

User.reflect_on_association(:location).to_hash.should == association_results

end


You can then use this method in any spec you want.

So, there you go Evgeny... not quite a one liner, but a lot easier to read!

blogLater

Mikel
Comments (12) :: Post A Comment! :: Permanent Link

¿ 22/7/2007 - Sweeet!!!

Posted by Evgeny
This looks beautiful!

But, any way to make this even prettier with the use of
"with_options"? (since we are dealing with hashes anyway)
Permanent Link

¿ 22/7/2007 - with_options?

Posted by mikel
Sure you could.

But what are you trying to achieve?

Maybe you can tell me, I can point you in the right direction and you can nut it out... I'll help you if you get stuck :)

Mikel
Permanent Link

¿ 23/7/2007 - Re: with_options?

Posted by Evgeny
Trying to find the best way to achieve a good rspec. since I am constantly thinking that I want to have a repository of really good specs that really check your stuff well.

For example, what you posted on your previous post :
Model.reflect_on_association(:association_model_name).should_not be_nil

It doesn't really check much, just that an association exists. And if you put a bunch of these together - like 6 for a user model, then you don't really know why they are there.

Now - a year later you edit the user model, and remove the counter_cache for example. You won't even notice a difference in the specs.

On the other hand, if you have counter_cache specified as well as the association - then you have a pretty good description of what it is and why it is there. The spec name.

If I am investing such a large amount of time in specs, I want them to really tell me whats going on when I no longer remember the code of the user model. So when something breaks or doesn't work, I won't miss it. Examples of things that may break is DB software version, Rails version, Rails plugin versions, etc ...

Too many times I spent days debugging a problem with no clue where it landed on me.

But on the other hand, if the spec is too long and not "beautiful", I won't remember it later on - and will want to re-invent the wheel.

to sum it up just in a word or two, "I guess I am a perfectionist of a sort." :)
Permanent Link

¿ 23/7/2007 - To Spec or not to Spec

Posted by mikel
Well, in my opinion, a spec is a spec when it fully specifies the application under development.

You might want to consider looking at Heckle. It is a program that modifies your code to see if your specs provide as much coverage as you expect.

Providing specs for what this brings up should cover you fairly well.

But again, spec what you write is a good maxim.

blogLater

Mikel
Permanent Link

¿ 23/7/2007 - Untitled Comment

Posted by Evgeny
Ohh, and I forgot to mention. I want to have as much "coverage" (with rcov) as possible. So even when rcov shows 100% coverage, that still might be lacking in the actual coverage.
Permanent Link

¿ 27/7/2007 - Untitled Comment

Posted by Anonymous
I found that this gave problems when running with autotest, although all was fine using rake spec.

The problem was with the class_name in the to_hash method. If I included a spec as you outlined in my test suite (with the code you suggested in spec_helper) and set autotest off on its merry way then on the first pass all is fine. If I then make an edit to the file containing the spec (say to the text in the 'it' bit it was failing the second time around on the :class_name part of the hash.

Changing the class name assignment to:

:class_name => @class_name || @name.to_s.singularize.camelize

fixes this. No idea why this happens mind you!

Cheers

Rupert
Permanent Link

¿ 27/7/2007 - Class name fix

Posted by mikel
Thanks Rupert,

I updated the code above (I found the same error).

Mikel
Permanent Link

¿ 29/7/2007 - Untitled Comment

Posted by Anonymous
no prob at all

...although it should be in the AssociationReflection. to_hash method in spec_helper, not in the spec itself (well, that's where I put it anyway)

Thanks for the post btw - found it very useful

Cheers

Rupert
Permanent Link

¿ 29/7/2007 - Oops...

Posted by mikel
stupid copy paste error. The above is now correct, thanks Rupert.
Permanent Link

¿ 10/8/2007 - RSpec Matcher

Posted by Steve Tooke
Mikel great couple of posts.

I've wrapped your solution up into an RSpec custom expectation matcher: http://stevetooke.karmatrading.co.uk/2007/8/10/simple-rails-association-matching-with-rspec
Permanent Link

¿ 8/9/2007 - :class_name =>

Posted by Anonymous
If I have belongs_to author, :class_name => person, foreign_key => author_id....

It seems the reflection's hash has class_name => Author and options =>{:class_name =>Person, :foreign_key=> author_id}

You code naturally checks against the unnested and bizarre :class_name => Author....and doesn't behave as expected.

still trying to work out why...
Permanent Link

¿ 9/9/2007 - Replies

Posted by mikel
@steve, Thanks!
@anonymous - could you show a bit more of your code... not quite sure what you mean here. Perhaps paste a link to a pastie...

Mikel
Permanent Link

¿ 22/7/2007 - How to test model associations in RSpec

Graeme Nelson has blogged about a great way to check all your model associations inside of RSpec.

Basically, the method you use:

Model.reflect_on_association(:association_model_name).should_not be_nil

This works using ActiveRecord's method "reflect_on_association" which returns the Class that the association belongs to/ has many of or whatever else :)

You can put a whole lot of these together and quickly and effectively test all the associations that you write into your models.

This keeps with the good testing practice of "Only test the code that you write".  As, when you set up an association, really, the only code you write is the "belongs_to" and "has_many's" or whatever else.

So why would you test that ActiveRecord handles this for you?  You wouldn't.  It would be a waste of time.  Better is to just test the association, which, from the point of view of what YOU wrote, is just the belongs_to has_many relationship and the model / class definitions.

blogLater

Mikel
Comments (3) :: Post A Comment! :: Permanent Link

¿ 22/7/2007 - Untitled Comment

Posted by Evgeny
How about:

association = User.reflect_on_association(:location)
association.macro.should == :belongs_to
association.class_name.should == 'Location'
association.options.should == { :counter_cache => true }

any way to spec all that (location + counter_cache) in one line?

Permanent Link

¿ 22/7/2007 - Reflection one liner

Posted by mikel
@Evgeny

Short answer, no.

Only ever so slightly longer answer, ABSOLUTELY! :)

Go to my newer post with nicely formated code in it.

http://www.blognow.com.au/q/67540/Reflect_on_association_one_liner_to_check_association_details.html

Mikel


Edited by mikel on 22/7/2007 at 2:59 AM
Permanent Link

¿ 23/7/2007 - nicely formatter code

Posted by Evgeny
I just fixed up my wordpress to format code properly too. Didn't think it would be so complex. Take a look http://blog.kesor.net - perhaps you will know some answers regarding my latest puzzle as well. :)
Permanent Link

About Me

AKA Raasdnil, this site is about web coding, hosting and all other matters that relate to this... especially Ruby on Rails!

Links