The calendar is gone.
Click here to view posts


Rails conf 2007
It's official I will be speaking at Rails Conf 2007!

Rails conf bio
Stephen Becker IV is a Cancer with a a smooth demeanor and a voice like velour. His turn-ons are long walks on the beach, futurama and all night caffeine induced bing programming sessions. His turn-offs are stupidity and the lack of velour clothing currently in stores. Presently working for Vonage as a rails developer in New Jersey.
Rails Conf link

Komodo 4
I use Komodo IDE at work and at home I would always use Rad Rails. That was the case until I started running 64bit suse. Rad Rails will not work for me, and it is not worth my effort to figure it out. Also Komodo just released 4.0!

I was sad at first because I did not see a price for a personal edition. So I am just the demo version of 4.0 and I found they have a free version which they call Komodo Edit. Found here ! I have yet to install the free version but if its close enough to the pay version I am set.

There is a big list some where of the features for komodo but there are only a few things that draw me to this product. Number 1 with out a doubt is the toolbox. I store bits of repeatable code and make them hot keys. This makes writing unit test, change logs, formatted rdocs comments so easy. I have also created a package for the tool box that includes the common RoR actions like rad rails has. That can be downloaded from here. Number 2 is the tab complete. In 4.0 you have to turn on the tab complete because its bound with different keys. I think they did a good job at guessing which word I want. They have an open that strips the whitspaces at the end of lines which includes those killer windows ^M's.

It is missing a few things that rad rails has. One is the hot key to take you from the controller to the view and back again. The auto formatting for indentation is very nice because sometimes i get out of control.

Rails generate generators
Creating a generator for rails is simple enough.[1] You have to create a directory in lib or vendor and call it generators. Then you create ruby class (Name)Generator that extends Rails::Generator::NamedBase or Rails::Generator. You create a method called manifest that will do the actions to for your generator.

In the manifest you call record with a block. Somethings you can do in the block?
#if options[:svn] is set this will run the svn add command
#I was creating controllers. this call checks name spaces of rails objects (Not user created objects)
#m.class_collisions class_path, "#{controller_name.camelize}Controller", "#{controller_name.camelize}ControllerTest", "#{controller_name.camelize}Helper"
#This just copies files from point a to point b.
#The file_options hash accepts :chmod and :shebang and :collision options.
#m.file "lib/rest_resource.rb", "lib/rest_resource.rb",{}
#m.directory File.join('lib','generators', class_name)
#this allows you to use ERB to create cool stuff
#m.template 'USAGE', File.join('lib', 'generators',class_name,"USAGE")
# Display a README.
#m.readme "INSTALL"

#I have yet to use these
#m.migration_template(relative_source, relative_destination, template_options = {:migration_file_name=>"not sure"})
#alters route.rb file
#m.route_resources(*resources)
#m.complex_template(relative_source, relative_destination, template_options = {[:assigns]['template_for_inclusion'] })
#check if its already there
#m.identical?(source, destination, &block)
</pre>
<br><br>
Simple enough so lets script it! Thats right I created a generator to create generators. <br>
<pre>
sbecker@funtime-theme-park:~/rails/gens$ ruby script/generate generator test
      create  lib/generators/test
      create  lib/generators/test/templates
      create  lib/generators/test/templates/controllers
      create  lib/generators/test/templates/tests
      create  lib/generators/test/templates/views
      create  lib/generators/test/templates/models
      create  lib/generators/test/templates/helpers
      create  lib/generators/test/templates/libs
      create  lib/generators/test/USAGE
      create  lib/generators/test1/test_generator.rb


The script creates the correct file structure,the generator.rb file and the templates folder with some default folders. If you do not need all these folders then delete them. I think it helps keep to the templates grouped together.

To create the generator I have two templates and the manifest. The templates are for the USAGE file which is from the controller USAGE, and a basic manifest which has example calls that i listed above. The manifest for the generator is simple.
class GeneratorGenerator < Rails::Generator::NamedBase
	attr_accessor :gen_path,:gen_name
	def initialize(*runtime_args)
		super(*runtime_args)
		raise "You need a Generator name" if runtime_args.first.size<1
                #class_name is auto formated and not reallly what i want
		@gen_name=runtime_args.first.first
                #simple check needs to be better
		raise " You already have a generator called #{gen_name}" if File.directory?(RAILS_ROOT+"/lib/generators/#{gen_name.downcase}")
		#the rest of the other actions, currently not used
                @actions = @args.empty? ? [] : Array(@args)
		@gen_path=@gen_name.downcase
	end
	def manifest
		record do |m|

			#Think of a way to check current gens
			m.directory File.join('lib','generators', gen_path)
			m.directory File.join('lib','generators', gen_path,'templates')
			m.directory File.join('lib','generators', gen_path,'templates','controllers')
			m.directory File.join('lib','generators', gen_path,'templates','tests')
			m.directory File.join('lib','generators', gen_path,'templates','views')
			m.directory File.join('lib','generators', gen_path,'templates','models')
			m.directory File.join('lib','generators', gen_path,'templates','helpers')
			m.directory File.join('lib','generators', gen_path,'templates','libs')
			m.template 'USAGE', File.join('lib', 'generators',gen_path,"USAGE")
			m.template 'generator.rb', File.join('lib', 'generators',gen_path,"#{gen_name}_generator.rb")
		end
	end
end


I will add the generator code to my svn soon.

Useful sites:
[1] http://wiki.rubyonrails.org/rails/pages/UnderstandingGenerators
[2] http://www.aidanf.net/rails/creating-your-own-generators-in-rails

Rails conf
Today was a fun day at Rails conf. I liked both my sessions I went to. I was a big fan of capistrano and now look forward to version 2.0. I am also looking forward to the sound features of the newest scriptaculous.
I give my talk tomorrow and I am very excited. I am also exited about portland. I like what i have seen of it so far.

Aftermath
I think the talk went well. I did not see a lot of people leaving. I will have to wait for the flood of blog posts. Which should be a lot because the room was packed. Some links to chew on CampFire transcript and Delicious page for vonage. Hopefully more to come soon...

Rails http head
As it turns out rails implements HTTP head calls for you. A fellow programmer was creating rails functional tests and using rcow noticed that we did not write test for the head command. He then found out that the functional test in rails when creating the mock response object includes the body like a normal get call. We reread the spec for http head one more time just in case we both thought incorrectly. So, I fired up the test using code komodo's ruby debugger. for the next 2 hours we stepped in the tes setup code and the rails frame work. We stepped in a lot of code until we hit the trunk/vendor/rails/actionpack/lib/action_controller/request.rb:line 16

# Returns the HTTP request method as a lowercase symbol (:get, for example). Note, HEAD is returned as :get
# since the two are supposedly to be functionaly equivilent for all purposes except that HEAD won't return a response
# body (which Rails also takes care of elsewhere).
def method
 @request_method ||= (!parameters[:_ethod].blank? && @env['REQUEST_METHOD'] == 'POST') ?
        parameters[:_method].to_s.downcase.to_sym :
 @env['REQUEST_METHOD'].downcase.to_sym
      
 @request_method == :head ? :get : @request_method
end


I did kept stepping in but I never found the code that takes care of the head body problem. We tested the head call using curl and it works, but the test returns the body like a normal get call.

So it must be code that is not ran for the testing frame work. Ihope to find the other code for the head call but I am having a hard time learning how to debug live rails apps.

Read up on your http head request here it is useful for caching. We all know what caching can lead to.

Just something i thought was cool.

First rails patch
I have posted my first rails patch. I will see how much I am laughed at and then decide on doing it again. I submitted a patch to exclude the directories of frameworks that are not needed. When I was stepping through the boot of rails I noticed it had a TODO next to it. The link is here. I hope they dont laugh to much.

Rails log parser
I started working on a rails log parser but there appears to be a very nice one on ruby forge. Since they have a lot of nice things i will not even finish the code I have in the SVN. From the little work I did with the log parser I did find out that %13.91 of my logged server requests had stack traces, and that %51.23 of the logged session ids are uniq. So I will check out the ruby forge project and see how that goes.

Action mailer recieving attchments
So I posted before about receiving voice mail and having populate on the internet. Well step one is checking the mail. As it turns out my email for my server is stored in a local dir. This is really good news because it appears that action mailer does not check email. First I need to add a receive method to my mail model:
    def receive(email)
		email
    end

Done! But you say it does nothing? I know. I hate changing code in models and then restarting the server. For now my logic will stay in the controller:

def test
#open the local file and read it in.
x=Notifier.receive(File.read("/home/giggles/realybadsite/1184671181.V9I760a7f6.popeyemail.com"))
#at this point x is a TMail::Mail (links below)
# x.attachments will be an array that has a TMail::Attachment which inherits from StringIO
# This holds the attachment ruby/gems/1.8/gems/actionmailer-1.3.2/lib/action_mailer/vendor/tmail/attachment.rb
# it also has original_filename and content_type
File.open(Dir.pwd+"/tmp/"+x.attachments.first.original_filename,"w+"){|file|
	file << x.attachments.first.gets
}

end


Now that I have access to the mail object and I can save the attached file I can now store the necessary data for my website.

For a list of methods on the TMail object try this website http://railsmanual.com/class/TMail::Mail

TMail

Rails upload file test
I wrote a rails service that can take a file as the posted params or data in the raw body. Like the good developer I am I wanted to create unit test for this functionally. Unsure how I could do this I search the Google for terms including but not limited to upload test file post rails with no good results. I did find fixture_file_upload which I now question what it really does.

I should have known the solution from odd test mishaps I have had before.
When you set params in the testing frame work they are passed as is.
For example:
x = Tempfile.new()
x.write = temp_file_data
x.rewind
post :service_x,:file=>x,value=>"x"

This will set param[:file] to a Tempfile like a normal mutil-part form post would. If you did not find this out already Rails will not always return you a Tempfile for posted files. If the file is small enough it will be a StringIO object. If you are reading the contents they will function the same real_data = params[:file].read . If you plan on resending the data you might want to check the kind_of? on the object that was passed in.

anyway good to know stuff.

Rjs partials
I was asked if one can do partial rjs files by a coworker recently. Some of our RJS code is becoming large and difficult to maintained. I figured why should RJS be different then the other templates. So I started up my test rails application. This is very filled with 1/2 crazy ideas and 1/2 unsure syntax examples. So I added two calls rjs1 and rjs2. I created a link_to_remote[1] on rjs1 pointing to rjs2. I did nothing in rjs2 but created an rjs2.rjs file in side of my views directory. My rsj2.rjs file looks like
page.replace_html "one","one"
page<<"#{render(:partial=>"moo")}"

_moo.rjs looks like
page.replace_html "two","two"
I understand that render will return the JavaScript of the rjs rendering. I also understand that I need to use page<< to append the JavaScript to the call like I would use <%= %> in an RHTML file. Would appear to work, but it seems off.

What I do not understand is why firebug[2] only shows me the first replace call in the response.
try {
Element.update("one", "one");
} catch (e) { alert('RJS error:\n\n' + e.toString()); alert('Element.update(\"one\", \"one\");'); throw e }

What it is close to what I expect to but not complete. This is what I think I should see:
try {
Element.update("one", "one");
try {
Element.update("two", "two");
} catch (e) { alert('RJS error:\n\n' + e.toString()); alert('Element.update(\"two\", \"two\");'); throw e }
} catch (e) { alert('RJS error:\n\n' + e.toString()); alert('Element.update(\"one\", \"one\");'); throw e }
Note the nested try catch is only there because of the rjs debug setting. So I changed debug to false and restarted the server. I now see this in firebug:
Element.update("one", "one");
Element.update("two", "two");

I am happy because this can help clean out view logic from the controller RJS calls, but I am also concerned that the improper display in firebug[3] can have a negative impact on developing JavaScript. I am also thinking that this can be done in a different way.



[1] http://api.rubyonrails.org/classes/ActionView/Helpers/PrototypeHelper.html [2] http://www.getfirebug.com/ [3] Firebug display issue

Rjs extensions
If you find your self using the page<< command a lot extend the page object.
module ActionView
  module Helpers
    module PrototypeHelper
      class JavaScriptGenerator #:nodoc:
        module GeneratorMethods
          def becker
            assign 'window.location.href', "http://stephenbeckeriv.com"
          end
        end
      end
    end
  end
end


Save this in a ruby file in the lib directory and then require "file_name" in environment.rb after the boot line.

Now you can call this from your rjs template.
page.becker


I do not have any good code examples. I am not a big javascript person which is why I am happy I can extend it in ruby.

Page render rjs
I recently posted about using RJS partials. I could of found out how to do this by searching the google. I found a nice site that sums up a peep code screencast.

I still think that this is an ugly way of doing this. It also has an extra debug statement that makes it look messy. So like my rjs extension example I created a partial render method. Odd little side note: I can not name my method render. I am looking in to why.
module ActionView
  module Helpers
    module PrototypeHelper
      class JavaScriptGenerator #:nodoc:
        module GeneratorMethods
          def partial(*args)
            reset_rjs_debug = ActionView::Base.debug_rjs
            ActionView::Base.debug_rjs = false
            @lines << "#{render(*args)}"
            ActionView::Base.debug_rjs = reset_rjs_debug
          end
        end
      end
    end
  end
end

Now your rjs script looks like
page.partial(:partial=>"moo",{:local=>"var"})

I do not like how the arguments repeat the partial. It would make more sense if I could call my method render (page.render). I also could do more with the arguments.
partial(name,*args)
...
@lines << "#{render(:partial=>name,*args)}"
I did not test this but it should work. Maybe there is a problem if no *args are passed in.

Rails rendering
No doubt any one looking at rails for speed will find that rendering sucks up a fair bit of time. I have two ideas to change the rendering system. The first is to remove the benchmarking code for production. I have no proof that this will make things faster. I am just sick of seeing it in my profiling log. The second idea I have is allowing the user of rails to change out rendering engines. For example using markaby instead of ERB or libxml(c lib) instead of XMLbuilder. I think using different libs could yield a faster render. If not with a c lib replacement then with another lib yet to be written.

Login generator
I have posted about my ruby on rails generator that generates generators before. When I created this I did not know the generator code that well. Sadly this is still the case. I used generators for my one task saving me from created a nearly similar files over and over again. But Becker could you have not metaprogramed it? No each model had a common idea and interface but in the end the code was very different. I could have reduced the code and created a mixin for most of the methods, but it's a little late for that. Also I do not think I want to create a mixin for code that should be changing a lot.
Long story shorter I created some generators. I found my self creating another rails app for my websites and I am writing the login code over and over again. I thought why not generate? Then I thought why has someone not done this? But they have and, each of the generators work. They all have good attributes and bad ones but, none of them are 100% what I wanted. So I am going to make my own login generator. I will post it in my svn when its ok. I also realize the literature on generators is lacking. I also feel that the amount of generators that have been created is very low. It might be the most under used feature in RoR.

Simple examples
Today a friend asked me how hard it would to create an inventory site for items. I asked him about the database and we came to the conclusion it was a single table problem. With in 10 mins I had a new rails app with migrations and scaffolding. Normally I do not like scaffolding but for a single table ugly app it works very well. After another 20 minutes I added a login and changed the form to use drop downs. Rails is by no means perfect, but it does make little things easy.

Kevin bacon search engine
I have come up with a new concept for search engines!

Kevin Bacon Page Ranks:
It takes a site and determines how many degrees from Kevin! That is your page rank. Or the inverse of that number. Depends if you like Kevin or not. The engine will have to be flexible enough to apply the same concept to other things like sports websites.

I am going to start mocking up the Kevin Bacon Page Ranker tonight in Rails.

Rails and soap4r
Recently at work I was tasked with making rails work with soap4r. There is a ticket on the soap4r trac[1] and in the Rails trac[2]. There are a wide range of solutions. I personally try to avoid changing core code if I can. With that in mind I have created two solutions.
In both solutions you need to not have soap4r install in the default gem folder. So gem install it in the Rails layout.
#since having soap4r installed will break all rail projects remove it.
sudo gem uninstall soap4r

sudo gem install --install-dir ~/rails_dir/vendor/gems soap4r
You can update the gem and remove it if needed. I see two negatives to this solution. One is that when I run IRB I do not have soap4r. This is solved by having it also installed in the normal gem dir on my dev box. Two there is going to be extra bandwidth with coping your rails code around. This can also be solved by installing it on your production boxes. If you have more then one prod box that could be a pain to remember to do.

Solution 1:
Set the GEM_PATH in the rails project:
Setting gem_path after require rubygems is a great way to keep soap4r in one project. The gem library is to use once you find the documentation. For some reason it is not listed on the ruby-doc website but you should have a local version of the docs. In your environment.rb file add
ENV['GEM_PATH'] = "#{File.dirname(__FILE__)}/../../../../gems"
require "rubygems"
Gem.clear_paths
or the location you installed the gems to. Then gem install your little hard way.

Solution 2:
Use rubygem classes:
rubygems is just another ruby class to load other ruby classes. Its one of the reasons we are in this mess to begin with. The good news is I have searched for example code and found nothing useful
    gems = Gem::SourceIndex.from_gems_in("~/local_gems")
    spec = gems.search('soap4r').last
    # straight from the gem requiring code base
    # bin directory must come before library directories
    spec.require_paths.unshift spec.bindir if spec.bindir
    soap_path = ""
    require_paths = spec.require_paths.map do |path|
      tmp = File.join spec.full_gem_path, path
      soap_path = tmp if tmp.include?("/lib")
      tmp
    end
    # straight from the gem requiring code base
    sitelibdir = Config::CONFIG['sitelibdir']
    # gem directories must come after -I and ENV['RUBYLIB']
    $LOAD_PATH.insert($:.index(sitelibdir), *require_paths)
    #for some reason I needed to require path/soap/soap I am sure I can fix that
    require File.join(path,"soap","soap")
As you can see most of it is just from the gem require process. All I added was the SourceIndex and soap path pieces. This code was my first fix. I tried like heck to set the gem load path but never made the connection to where it was first loading rubygems. This solution fails with requiring a gem, using versions, and preventing the gem from being loaded again. All things that can be fixed but I did not post the code. I am thinking about extending rubygem to allow you say gem name,revision,location.


[1] http://dev.ctor.org/soap4r/ticket/433 [2] http://dev.rubyonrails.org/ticket/10001

Email rendering
I have convinced ActionController to render email templates for me. This allows me to use all the ActionView HTML helpers.