Peter's Blog

Redefining the Impossible

Items filed under noob


One of the things that is offputting about learning any of the web application stacks that I have tried (rails, turbogears, django) is the command line operations that need to be performed. When you start using them they seem like magic but after a while they become old friends. Hence this article is a summary of the rails command line operations that I use routinely.

All these commands except for the first one should be executed in the root directory of your application. Note that for the commands that start 'script' you are running ruby scripts and under windows you will need to type 'ruby script/blah'.

rails {app name}

The basic one, creates a new rails application. It will create a subdirectory with the given name in the current directory. This subdirectory is the root directory of your application and will be filled with all the appropriate files and subdirectories to start developing. It is a big code generator.

script/server

This could be considered the next step after creating your application. You cd to the application's root directory and run this command. It will start a development web server and you will be able to connect to localhost:3000 in a web browser and admire your new creation. This is the way to debug your application. Any print statements will be dumped out here.

script/generate model {model name}

This command will generate a new model in your application. A model is roughly equivalent to a table in the database.

script/generate controller {controller name}

This command will generate a new controller in your application in the file 'app/controllers/{controller name}_controller.rb'. A controller is essentially the logic that takes a web page request and decides what to do with it. It will also create a directory called 'app/views/{controller name}' to store the views for this controller, views being the templates that determine how the web pages will look.

rake db:migrate

This runs the migrations that will either define the database schema, modify it or undo those modifications. It defaults to updating the development database but can take the argument 'RAILS_ENV=production' to update the production database.

script/console

script/console is useful for debugging. It gives you a ruby irb command line prompt where you can play with the inner workings of your code, primarily you have direct access to your models and hence the database. It can be an easier way of manipulating the database from a command line than typing SQL into the mysql or sqlite command line clients.

rake --tasks

Lists what rake tasks are available.

rake db:test:prepare

Prepares the test database for running unit tests.

rake test

Runs all unit, functional and integration tests on your model.

I think that covers it. There are many more options than these are the ones that I have found to be most useful.


Filed under: noob rails

Add a comment

Sometimes software jargon gets in the way of understanding what practical use something is. For example, you have a problem and you want to know how to solve it so where do you look it up in the ruby book?

What I am going to describe is based on the concept of 'metaclasses' which are classes for creating classes. If that jargon fried your brain then lets have a problem and an example.

I want to create classes for implementing Commands. Each Command class has a command number and I want to define this Command Number in the class definition but I don't want to wear my fingers out typing them in. What nice syntactic sugar can ruby offer to help me with this?

   1  #
   2  # Class for building command classes
   3  #
   4  class Command
   5    class << self
   6      attr :nCommandNumber
   7  
   8      def CommandNumber( nNumber)
   9        @nCommandNumber = nNumber
  10      end
  11    end
  12  end

Ok, horrible syntax so what on earth is going on here? Well the effect of 'class << <object>' is to add new methods to an object so in this case we are adding a new attribute 'nCommandNumber' to hold our command number and a new method 'CommandNumber' so set its value to an object referred to by 'self'.

So what is 'self' equal to? Well it turns out that when you use this class (Command) to create another class (ACommand) then 'self' will hold the value of the 'ACommand' class object, i.e. the object that creates instances of ACommand objects.

#
# Declare a specific command
#
class ACommand < Command
  CommandNumber 123
end

Hum, that looks easy. When ACommand is being defined the line 'CommandNumber 123' will result in the CommandNumber method in Command being executed on the ACommand class object so 'ACommand' will have an attribute called nCommandNumber added to it. We can see whether this happened with:

print ACommand.nCommandNumber
=>123

and indeed it works sweetly (which is what you would expect from syntactic sugar). It is important to note that it is the ACommand class itself that has these attributes, NOT objects CREATED by ACommand:

oAC = ACommand.new
print oAC.nCommandNumber
NoMethodError: undefined method `nCommandNumber' for #<ACommand:0x345e180>
        from (irb):15

so how can an object created by ACommand find the value of this attribute?

oAC.class.nCommandNumber
=> 123

one of the attributes of the object is the class that created it.

How would this be done in a lesser object orientated language? Probably using techniques such as:

   1  class Command
   2    def GetCommandNumber
   3       raise RuntimeError, "Pure base function called"
   4    end
   5  end
   6  
   7  class ACommand < Command
   8    def GetCommandNumber
   9       return 123
  10    end
  11  end

or

   1  class Command
   2    def initialize( nCommandNumber)
   3      @nCommandNumber = nCommandNumber
   4    end
   5  end
   6  
   7  class ACommand < Command
   8    def initialize
   9      super( 123)
  10    end
  11  end

or something similar. Like all syntactic sugar, it doesn't make the impossible possible (anything is possible in hand-coded assembler) it just makes for less typing and clearer code.


Filed under: noob ruby

Add a comment

Found another ruby gotcha when calling methods declared with default argument values:

irb(main):004:0> def a( b=1,c=2,d=3)
irb(main):005:1> print "#{b} #{c} #{d}\n"
irb(main):006:1> end
=> nil
irb(main):007:0> a(c=23)
23 2 3
=> nil

A python programmer would have expected this to print

2 23 3

as when calling the function we are saying we want c to be 23 and the other arguments to be left at their default values. Ruby appears to be ignoring the 'c=' bit when the function is being called so the first argument 'b' gets the value 23.

Pity, this python trick simplifies calling functions with lots of default parameters: you don't have to get the order of the parameters right or specify the correct default values of arguments before the one you are having to specify a value for. I should be calling this with:

irb(main):007:0> a(b=1, c=23)

i.e passing 'b=1' even though the declaration should tell ruby what the default for that should be. The 'b=' and 'c=' are only serving to help me selfdocument my code.

Ruby's behaviour is C/C++ish i.e. primitive.

UPDATE:

O'Reilly Ruby Cookbook:

   1  def fun_with_text(text, args={})
   2    text = text.upcase if args[:upcase]
   3    text = text.downcase if args[:downcase]
   4    if args[:find] and args[:replace]
   5      text = text.gsub(args[:find], args[:replace])
   6    end
   7    text = text.slice(0, args[:truncate_at]) if args[:truncate_at]
   8    return text
   9  end
  10  
  11  fun_with_text("Foobar", {:upcase => true, :truncate_at => 5})
  12  # => "FOOBA"
  13  fun_with_text("Foobar", :upcase => true, :truncate_at => 5)
  14  # => "FOOBA"
  15  fun_with_text("Foobar", :find => /(o+)/, :replace => '\1d', :downcase => true)
  16  # => "foodbar"

Filed under: gotcha noob ruby

2 Comments

I'm going to blog this so I can remember it. How to get Rails/ActiveRecord to wrap an existing table in a database, i.e. one that you don't want created or manipulated via migrations:

ruby script/generate model my_table --skip-migration

where my_table is the name of the table you are wrapping. This assumes you are already connected to the database (easy: edit config/database.yml).

It may be possible to simply derive a new class from ActiveRecord but the above is probably ensuring that everything is done properly.

In my case the database is being stuffed from some complex python code that I don't have the time/inclination to port to ruby/rails and I would rather the creation of the tables was still done through python. ActiveRecord being the wonder that it is will pick up the schema of the table and create wrappers automatically so you still don't need to tediously reiterate the column names/functions as you would in lesser frameworks.

It should be entirely possible to create views in MySQL and wrap them for Rails in this fashion although I found that creating views on a 20,000 record table causes the mysqld to take 99% cpu time for ten minutes afterwards. I know what you're saying, 'check your indexes', well I have.


Filed under: mysql noob rails

Add a comment

I've been looking into why the make facilities in my Eclipse/CDT install are not working (I try a make and nothing happens). I found a log file in my workspace folder called /.metadata/.log and the log file contains this:

!ENTRY org.eclipse.core.resources 4 2 2007-11-28 11:13:09.401
!MESSAGE Problems occurred when invoking code from plug-in: "org.eclipse.core.resources".
!STACK 0
java.lang.NullPointerException
  at org.eclipse.cdt.managedbuilder.internal.core.CommonBuilder.build(CommonBuilder.java:520)
  at org.eclipse.cdt.managedbuilder.internal.core.CommonBuilder.build(CommonBuilder.java:506)
  at org.eclipse.core.internal.events.BuildManager$2.run(BuildManager.java:624)
  at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:37)
  at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:166)
  at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:273)
  at org.eclipse.core.internal.events.BuildManager.build(BuildManager.java:354)
  at org.eclipse.core.internal.resources.Project.internalBuild(Project.java:494)

So the java is hitting some runtime error and the architecture is so poor that the error is not reported to me, I have to sit there wondering why nothing is happening.

I searched through the eclipse plugin directory and found zip files that contained the source code. The error in the log pointed me to this line:

IConfiguration activeCfg = info.getDefaultConfiguration();

so my guess was that getDefaultConfiguration was returning a null. This tied in with an observation I made that the "Build Configurations" menu in Eclipse/CDT had all it's items greyed out, including 'Manage..'. I decided that it was probably all because I hadn't set up my CDT project properly. I created a new CDT project, imported my source into it, deleted the old project, renamed the new project to match the old and tried it out. Voila, make ran and the output was in the console.

Lessons learnt:

  • Projects may work with a number of perspectives (e.g. C/C++, Ruby etc) and each perspective wants it's configuration data within the project set up properly. At the same time, they seem only to set these configurations up when you create new projects, adding configuration data to an existing project when you use a new perspective appears to be up to the individual plugins: RDT, the ruby development plugin has an 'add ruby nature' option in the project menu to do this.
  • Because Eclipse is written in java it comes with all the source code. This means that even if some of it is a bit flaky one stands a good chance of working around the problems.

Ok, I'm an Eclipse noob and didn't set my project up correctly but the environment really ought to have handled this better.


Filed under: eclipse java noob

Add a comment

I was trying to use blocks in ruby and had code of this form:

   1  
   2  def wangle
   3      while true
   4          nValue = rand(10)
   5          if yield( nValue)
   6              return
   7          end
   8          print "THIS IS NEVER PRINTED"
   9      end
  10  end
  11  
  12  def wibble
  13      wangle do |nValue|
  14          return nValue == rand(10)
  15      end
  16  end
  17  
  18  wibble()

The method 'wibble' calls 'wangle' passing it a block of code to execute. Wangle is supposed to keep calling this block until two random numbers match. if the numbers match it will return true and cause the loop to terminate. However, the loop will always terminate immediately, the string "THIS IS NEVER PRINTED" is never printed.

The reason for this is blindingly obvious in hindsight and after analysing the small print describing the yield command. This says "the value of the last expression evaluated in the block is passed back to the method as the value of the yield". Notice how it doesn't mention the 'return' keyword? This is because the return keyword is being applied to the outer method 'wibble' and that is returning to whatever called it, completely bypassing 'wangle' on it's way up the call tree. If 'wibble' is changed to:

def wibble
    wangle do |nValue|
        nValue == rand(10)
    end
end

then it will pass the results of the comparison "nValue == rand(10)" back to wangle to deal with as I originally intended.

I can imagine that this subtlety was permitted as there may be occasions when you want wibble to be able to return directly to it's caller. In my ruby noobyness I'm getting blocks mixed up with methods. Unfortunately I like using the return keyword, it makes code easier to skim read, it waves a big flag to me that says THIS IS THE RETURN VALUE.


Filed under: noob readthesmallprint ruby

Add a comment

This is all very noobish but it was about time I learned more about the du command. du means 'disk usage' and lists how much disk space is being used. At its most basic

du

dumps out a list of subdirectories under the current directory and shows their sizes in magic pixie units. First improvement is to show the sizes in something meaningful so we go

du -bh

to show sizes in 'human' readable units like Kbytes, Mbytes etc.

du normally dumps the sizes of files in subdirectories so we can go

du -bsh

to show just a sum total.

Now what if we find to our horror that a directory is using far more space than we thought, how to determine how big each subdirectory is?

du -bsh *

Filed under: linux noob

3 Comments

Syntactic Sugar

Ruby has some perlisms such as 'unless'. This makes it possible to write code as follows:

return unless bFlag

Without unless one may have to resort to:

if !bFlag
  return
end

I think code is easier to read when lines start with keywords, when the keywords are further inside a line one has to rely on syntax highlighting to make the keyword shout out at you. This is especially important with a keyword like return where you have to be aware that the code in the lines following may not be executed and understand the circumstances in which this will apply.

This way of expressing a statement always seems harder for me to get my head around, having written in C like languages for years. If one wrote similar expressions in English, which seems to be better expressed?

  • jump up and down and sing a merry song if you are happy
  • if you are happy then jump up and down and sing a merry song

To me the second form is even clearer as having the if at the start warns you in advance that a condition is coming up, it's not a surprise half way through the sentence. However, the second form requires you to type a whole extra word, and a four letter one at that!


Filed under: noob ruby

1 Comment

Ooh Err, has_and_belongs_to_many, how_can_a_keyword_be_so_long?

Anyway, I've just used it for the first time to implement a UI in rails for user role permissions and here are some notes so that I might be able to use it again without excessive code trawling.

has_and_belongs_to_many is used to define many to many relationships. In the system I am implementing I have many Users and many Roles for them to perform. A User can be assigned to many Roles and a Role may be assigned to many Users. This is a classic many to many relationship and is implemented by having a table that contains a list of mappings of user id to role id, one mapping for each assignment of a user to a role.

This is (essentially) the migration that is used to create the user that is created by acts_as_authenticated but here it is stripped to the meaty bits:

   1  class CreateUsers < ActiveRecord::Migration
   2    def self.up
   3      create_table "users", :force => true do |t|
   4        t.column :login, :string
   5      end
   6    end
   7  
   8    def self.down
   9      drop_table "users"
  10    end
  11  end

This is the migration that the role_requirement plugin uses to create the roles tables:

   1  class CreateRoles < ActiveRecord::Migration
   2    def self.up
   3      create_table "roles" do |t|
   4        t.column :name, :string
   5      end
   6  
   7      # generate the join table
   8      create_table "roles_users", :id => false do |t|
   9        t.column "role_id", :integer
  10        t.column "user_id", :integer
  11      end
  12      add_index "roles_users", "role_id"
  13      add_index "roles_users", "user_id"
  14    end
  15  
  16    def self.down
  17      drop_table "roles"
  18      drop_table "roles_users"
  19    end
  20  end

In summary, there are three tables in the database:

  • A 'users' table with a field called 'login' that gives the user login name
  • A 'roles' table with a field called 'name' that gives the name of the role
  • A table called 'roles_users' that holds each assignment of a role to a user.

Models need to be created for the User and Role table but not the roles_users table as that one is handled automagicaly by rails.

Here are the meaty bits of the model for the User table:

class User < ActiveRecord::Base
  has_and_belongs_to_many :roles

  validates_length_of       :login,    :within => 1..40
  validates_uniqueness_of   :login, :case_sensitive => false
end

And the model for the Role table:

class Role < ActiveRecord::Base
  has_and_belongs_to_many :users

  validates_presence_of :name
  validates_uniqueness_of   :name, :case_sensitive => false
end

Both these have the magical has_and_belongs_to_many declaration to invoke the many-to-many goodness. They also perform some validation on what the user enters such as making sure they are giving their users login names.

Now for some code for a partial that can be used in a view to edit or create user records. This is used to generate a list of check boxes, one for each role. The check box will be checked according to whether or not the user has been assigned that role:

   1  <% form_for :user, :url => { :action => action, :id => @user} do |f| %>
   2  
   3      <p>Enter the login name for the new user:</p>
   4  
   5      <div style="margin-left: 50px; margin-bottom: 50px">
   6        <%= f.text_field  :login %>
   7      </div>
   8  
   9      <p>Select the Roles that this user can perform</p>
  10  
  11      <div style="margin-left: 50px">
  12          <table>
  13              <% for oRole in Role.find(:all, :order => :name) %>
  14                  <tr>
  15                      <td>
  16                          <%= check_box_tag "user[role_ids][]", oRole.id, @user.roles.include?(oRole) %>
  17                      </td>
  18                      <td>
  19                          <%= oRole.name %>
  20                      </td>
  21                  </tr>
  22              <% end %>
  23          </table>
  24      </div>
  25  
  26      <%= submit_tag submit_tag %>
  27      <%= submit_tag "Cancel" %>
  28  <% end %>

Here we iterate through all the Roles in the role table, sorted into name order. For each role we generate a check box tag. The check_box_tag line is tricky but can be broken down as:

"user[role_ids][]"
this is the name for the check box tag field. Naming the check box like this ensures that when the form is posted back to the server, the values for each tag will be placed correctly in the params array
oRole.id
the id of the Role record for this checkbox. It is these ids that are stored in the roles_users table to map a user id to a role id.
@user.roles.include?(oRole)
from the current user record, search the list of roles mapped to that user and see if the list already contains a particular role. If it does then the checkbox will be checked when the form is displayed.

When the form is submitted we need to ensure that the roles mapped to a user are updated correctly. This is simple:

   1  def update
   2    strLogin = params[:user][:login]
   3  
   4    oUser = User.find( params[:id])
   5    oUser.login = strLogin
   6    oUser.role_ids = params[:user][:role_ids]
   7    oUser.save!
   8    flash[:notice] = "Updated User '#{strLogin}'"
   9  
  10    redirect_to :action => :list
  11  end

This is the method in the user controller that updates an existing record. The juicy bit is the line

oUser.role_ids = params[:user][:role_ids]

which is ALL it takes to update all the role assignments! This saves a lot of work such as adding new role assignments and removing extraneous ones.

Another little thing to watch out for: when deleting a role or a user do NOT use the delete method:

User.delete( params[:id]) ## WRONG

delete apparently just sends the raw sql to the database engine to get it to delete the object. Instead you should call destroy:

User.destroy( params[:id]) # Delete user and database objects associated with him/her

destroy will invoke the rails Active Record magic that will cause the roles_users table to be updated, removing any entires for roles or users that are being deleted. Calling delete will not do this and will leave stray records in the database.


Filed under: noob rails

3 Comments

Endless Ends

Ruby terminates just about everything with the end keyword:

def SillyExample
  if a == 3
    10.repeat do |n|
      if n == a
        print n
      end
    end
  end
end

Maybe I am nesting too deep but the endless ends become quite confusing after a while, especially with ruby's official two space indents. Visual Basic 6 (ugh) at least has end if, loop, end sub etc so you know what you are looking at the end of.

Then again, python has no equivalent to end:

def SillyExample():
    if a == 3:
        for i in range(10):
            if n == a:
                print n

but python's indentation standard is four spaces rather than two making it a bit easier to follow.

Maybe I should just defy convention and indent my ruby with four spaces? Who cares apart from the indentation Nazis?

More Scope for Errors

So why wasn't this loop doing what I thought it would?

Mytable.find( :all, :order => "serial_number") do |oRecord|
    print oRecord.serial_number
end

Mytable is a rails ActiveRecord class and I'm using it to load records from a table. But nothing is printed although I am sure there are records there.

Hum, turns out I missed the call to the 'each' method:

Mytable.find( :all, :order => "serial_number").each do |oRecord|
    print oRecord.serial_number
end

and now it iterates through the recordset correctly. It seems that the first form silently does nothing, it doesn't seem to execute anything inside the block. It gives no errors either.


Filed under: noob ruby

1 Comment