Posted by Richard White
Thu, 23 Feb 2006 18:33:42 GMT
Ever since I migrated to typo I’ve been wondering what was up with the article and comment timestamps. Obviously something seemed wrong when every comment and article was showing up as being created at the same time. For whatever reason the idea that Typo could be getting something as basic as the timestamp wrong seemed preposterous so I assumed this was only some problem manifested by gremlins in my browser (and the fact that I’ve been preoccupied with all sorts of other things made this a good excuse).
I finally worked up the nerve to look at the database table today and realized that while all the updated_at dates were correct on comments the created_at were all the same (I had been manually adjusting the article timestamps through the admin interface so these weren’t incorrect)! Initial research yielded little especially for a problem that would seem to be very pervasive amongst Typo users. I eventually found ticket on the Typo trac which claims that this is actually a RoR 1.0 bug. Thankfully patching this issue is relatively simple.
The final piece was to fix existing comments which I basically did by renaming the updated_at field to created_at and vice versa.
I’m a little peeved at myself for letting this go so long but hopefully it’ll be smoother sailing from here on in. Then again selecting categories when I create an article still doesn’t work so who knows what else is wrong with Typo.
Posted by Richard White
Wed, 22 Feb 2006 17:36:00 GMT
AjaxScaffold has been deprecated in favor of ActiveScaffold
* rwhite 2/23 – All these issues have been fixed as of version 2.1.0 read more about it here*
I’ve gotten a couple emails about some issues with the Ajax Scaffold Generator, here is the current list I have:
The good news is that I have patch almost all of these in my dev environment and should have a point release out by the end of the week. I’ll try to keep a running list of known issues on the demo page, but in the meantime just leave a comment on this article of any issues you come across.
Posted by Richard White
Tue, 21 Feb 2006 02:05:00 GMT
AjaxScaffold has been deprecated in favor of ActiveScaffold
So I just gemmed and uploaded the v2.0 release of the ajax scaffold generator. There are quite a few improvements in this version, most notably:
- The generated scaffold code looks production ready: valid XHTML, CSS, fully styled.
- It now uses a <table>
- Its designed to be used as a component so you can easily create an admin console with a couple generated scaffolds.
- A number of CSS styles have already been included for commonly used elements like required field labels, example field input and for some basic form layout control (explained later in this article).
- Works on Firefox 1+, IE 6+ and Safari 2+ (It may work on others, but I haven’t tested anywhere else, so let me know what you find out)
Why not jump over to the demo page and check it out and then come back here for the walkthrough. (and it wouldn’t hurt if you went and Dugg this article somewhere in between ;) ).
Some of this information is outdated as of version 3.0.0, check out the 3.0.0 release notes
Getting Started
Getting up and running is fairly straightforward, but I’ll hold your hand just in case :)
- Install the Ajax Scaffold Generator gem
gem install ajax_scaffold_generator
Create a database table (using Rails Migrations hopefully) and configure your config/database.yml
Run the generator against the database table you just created, for our purposes here our table is named widgets our model is named Widget and our controller is named Widget (generation options are the same as for the regular Rails scaffold which you can read about here).
ruby script/generate ajax_scaffold Widget
or on *nix
script/generate ajax_scaffold Widget
Start up WEBrick or whatever RoR server you use and go to http://localhost:3000/widgets/ (obviously this will be different depending on what you have named your objects and if you are running on something other than the default WEBrick port)

Thats it! You have a fully working ajaxified scaffold page.
Adding form validation
Of course we probably want to add some validation to our objects so lets start by making widget.name required.
We add the following to models/widget.rb
class Widget
<strong>validates_presence_of :name</strong>
end
And now for some UI sugar we will add a class and an asterisk to the name label in views/widget/_form.rhtml:
<div class="form-element">
<label <strong>class="required"</strong> for="widget_name">Name<strong>*</strong></label>
<%= text_field 'widget', 'name' >
</div>
And now when we attempt to create a widget without a name we get this helpful message.

UI Sugar
I also find it good practice to give people examples of what their form input should look like (help text is good too but I prefer examples). So lets put an example on the version field:
<div class="form-element">
<label for="widget_version">Version</label>
<%= text_field 'widget', 'version' %>
<strong> <label class="example">ex: v1.0, v0.2.4, rc4</label></strong>
</div>
Obviously putting the example under the input is just personal preference and when I have client-side errors I will usually put the example on top, but thats neither here nor there.
Next I may want to make sure that a certain set of fields always appear on a new line. A good example of this might be a situation where I want First Name and Last Name on one line and Address to always be on a line beneath those two elements. To accomplish this we simply wrap each “section” of form elements in a <div class=”row”> in our views/widgets/_form.rhtml:
<fieldset>
<strong><div class="row"></strong>
<div class="form-element">
<label class="required" for="widget_name">Name*</label>
<%= text_field 'widget', 'name' %>
</div>
</div>
<strong><div class="row"></strong>
<div class="form-element">
<label for="widget_version">Version</label>
<%= text_field 'widget', 'version' %>
<label class="example">ex: v1.0, v0.2.4, rc4</label>
</div>
</div>
</fieldset>
And voila!

General Error Messages
This information is outdated as of version 3.0.0, check out the 3.0.0 release notes
Handling when something goes very wrong is an oft overlooked part of many systems. Your generated scaffold has a fairly simple way of passing general errors back to the user. For the same of example I am going to short circuit the controller method for creating a new widget to always return one of these general errors:
def new
...
#render :layout => false
<strong>render :inline => "Muwhahah! No new widget for you!",
:layout => false, :status => 500</strong>
end
Now watch what happens when I try to create a new widget:

Ouch denied!
Embedding multiple scaffolds on the same page
One of the beauties of AjaxScaffolds is that they are designed to be used as components that you can embed on other pages. I’ve documented this in a later article here.
A Few Caveats
There are just a few caveats to all of this. These should hopefully be resolved in future versions (which anyone is more than welcome to pitch in on).
Future Direction & Wrapping Up
Well that’s is about all we have for the first release of Ajax Scaffold Generator v2.
Just to give you an idea of where we are going here are some future improvements in the development queue:
- Make the tables sortable
- Export table data to CSV
- Ability to specify different types of messages sent to the client (info, warning, etc) without having the operation fail (ie not having to set status = 500)
- Have it update regularly to pick up on changes made by other users
- Client side validation
- Use JSTs to create the forms (update, create) to save server requests
- Print stylesheet
- Fix those caveats I listed previously
Undoubtedly, as with any first release, there will be some bugs to please forward those and any feedback you might have either via the comments on this blog or by email me at rrwhite AT gmail.com.
And finally, I need to give a shout out to Mark James for his Silk icons and stay tuned to this blog as I’ll be writing up more of the interesting implementation details and technical workarounds that I had to do to make this all work (If your into that sort of thing).
Happy generating.
Posted by Richard White
Mon, 20 Feb 2006 17:46:00 GMT
I spent the better half of yesterday migrating this blog to Typo and bringing the associated articles on the old one over. I was originally just using a Blogger account that was being SFTP’d to my web server. That was a decent solution for a blog when you want a quick and dirty way to get started. But it was time to move to something with a little more flexibility and credibility(?). It also forced me to learn how to configure lighttpd to handle multiple Rails applications on the same domain (what other apps are on this domain you say? you’ll see, you’ll see).
In the process of converting to Typo I needed to migrate my look and feel. In Typo it was easy enough to do this by creating a new theme, which is exactly what I did and I named her Brighthouse. You can download the theme from the resources link on your right. I’ll go ahead and include my short configuration instructions here so they’ll be easier to find (you can also find them in about.markdown which is what shows up when you import the theme into Typo.
Unfortunately I cannot find any good sites that keep a list of Type themes. I found this page on the Typo trac, but it looks like it hasn’t been updated lately. There is also TypoGarden that recently put on a theme contest. There are some themes on there but you have to search back through their post archives and there appears to be no concise list or way to upload new themes. Let me know if you know of any Typo theme sites.
Getting Started with Brighthouse
- Download the zip file and extract it into your themes directory in Typo
- Add your personal information to the about box in /themes/brighthouse/layouts/default.rhtml
- Add your headshot photo into /themes/brighthouse/images/headshot.gif_(of course you can change that url in the default.rhtml)
Optionally you can create static sidebar lists with specialized list icons using <ul class="resources"> and <ul class="feeds">
Posted by Richard White
Mon, 20 Feb 2006 15:46:00 GMT
A few days ago I mentioned some of my struggles with the acts_as_paranoid Rails plugin. I also mentioned that I solved my problem with making an association to a paranoid model ignore the delete_at field. Unfortunately my fix was not properly tested and does not actually work. When I redefined the def task method I broke def task=.
My workaround to this was a simple, but very ugly, hack. I removed def task and replaced it with the following method.
def task_wrapper
if self.task.nil?
self.task= Task.find_with_deleted(task_id) if task_id != 0
end
self.task
end
Which is basically prefetching that association using the find_with_deleted method given to you by acts_as_paranoid. I would call this method any time before I need to call object.task. See, told you it was messy.
I would have spent more time coming up with a better solution but I soon realized what I was doing had a very funny odor to it. That’s right ye olde dreaded CodeSmell. I remodeled the whole association to better reflect what I was trying to accomplish and now do not use acts_as_paranoid at all (well at least in this case).
Just wanted to followup lest anyone actually think I got it right the first time.
Posted by Richard White
Sat, 18 Feb 2006 02:06:00 GMT
One of the most frustrating parts of Rails Migrations is the fact that each migration is
NOT transactional. Its possible that some query halfway through the migration could fail and leave you database schema in a
“bad state”. After reading this blurb on
RailsBestPractices on the
RoR wiki I thought that it might be possible to wrap my migrations in a simple transaction, with the only caveat that it won’t work for MySQL:
... Put a transaction around your migrations. That way, you know that you won’t be dumped out half-way through a migration, and have to disentangle whatever half-finished mess you end up with to try to run it again. The slight crimp to this is that MySQL doesn’t allow data definition commands (like CREATE TABLE, for instance) inside a transaction, and they cause an implicit commit. It’s still a good idea for data-only migrations, though.
Unfortunately the following does not work
class TestTransaction
self.up
<strong> transaction do</strong>
create_table :widgets, :force => true do |t|
t.column :name, :string, :null => false
t.column :version, :string, :null => false
end
remove_column :widgets, :type
end
end
...
Because when I run
rake migrate I get the following
rake aborted!
RuntimeError: ERROR
C25P02 Mcurrent transaction is aborted, commands ignored until
end of transaction block
Fpostgres.c L926 Rexec_simple_query: CREATE TABLE cars
("id" serial primary key, "make" character varying(255) NO
T NULL, "model" character varying(255) NOT NULL)
If anyone has any ideas drop me a line rrwhite AT gmail.com
Update: Thanks to Eric Pugh for pointing out that removing :force => true makes this work!
Posted by Richard White
Mon, 13 Feb 2006 02:06:00 GMT
Installed the
acts_as_paranoid plugin today for a top secret project I am working on. The documentation is quite lacking so I’ll fill in a few holes here. This may be obvious to everyone else out there but in order for it to work you need to add the following to the end of your
environment.rb file:
require_gem 'acts_as_paranoid'
Doing this got rid of the 500 error I was encountering, but my objects were still being outright deleted, instead of having the
deleted_at field set. A checked of the
development.log showed that
tasks.deleted_at IS NULL was being injected into
SQL queries. So obviously the plugin was working on some level. My class looked like the following:
class Task
acts_as_taggable
<strong>acts_as_paranoid</strong>
For grins I tried swapping those two acts_* statements:
class Task
<strong>acts_as_paranoid</strong>
acts_as_taggable
And it started working correctly! Not sure the cause of this I’ll try and ping the developers for
acts_as_paranoid.
Also, while for the most part I wanted deleted items to not show up in any associations there were a few where I still wanted the deleted association to be retrieved. I solved this by adding the following:
class TimeEntry < ActiveRecord::Base
belongs_to :task
def task
<strong>Task.find_with_deleted(task_id) if task_id != 0</strong>
end
If you know of a more elegant way to do this, drop me a line and let me know.
Posted by Richard White
Sat, 04 Feb 2006 02:06:00 GMT
Encountered another issue with migrations today when trying to do the following
add_column :appt_service_logins, :id, :primary_key
This threw an error when running
rake migrate against my PostgreSQL DB that essentially boiled down to migrations trying to run the following
SQL
ALTER TABLE appt_service_logins ADD id
Obviously missing the datatype for the column. I tracked this down to type_to_sql returning nil. This was because
def native_database_types define a Hash where primary key does not map to another Hash with a :name key (see previous post). Therefore the following in
def type_to_sql would return nil since it specifically looks for the value using the :name key.
def type_to_sql(type, limit = nil) #:nodoc:
native = native_database_types[type]
limit ||= native[:limit]
column_type_sql = native[:name]
column_type_sql << "(#{limit})" if limit
column_type_sql
endTo get around this I modified
def type_to_sql to use the
native value if
column_type_sql was nil.
def type_to_sql(type, limit = nil) #:nodoc:
native = native_database_types[type]
limit ||= native[:limit]
column_type_sql = native[:name]
column_type_sql << "(#{limit})" if limit
if column_type_sql
column_type_sql
else
native
end
endI have no idea what the implications of such a change would be which is why I submitted this as a
bug.
In the meantime since I was worried about the implications of changing def type_to_sql, I added a native database type of bigserial and am adding the column as a non-null bigserial and with a unique index.
Changes to postgre_extensions.rb:
def native_database_types
{
:primary_key => "bigserial primary key",
:string => { :name => "character varying", :limit => 255 },
:text => { :name => "text" },
:integer => { :name => "integer" },
:float => { :name => "float" },
:datetime => { :name => "timestamp" },
:timestamp => { :name => "timestamp" },
:time => { :name => "time" },
:date => { :name => "date" },
:binary => { :name => "bytea" },
:boolean => { :name => "boolean" },
:bigint => { :name => "int8" },
<strong>:bigserial => { :name => "bigserial" }</strong>
}
endIn self.up in the migration file:
add_column :appt_service_logins, :id, :bigserial, :null => false
add_index :appt_service_logins, :id, :unique
To wrap up I attempted to put all of my changes into a Rails plugin so I wouldn’t have to put
require ‘postgre_extensions’ at the top of each migration file as
this fellow did but to no avail. I settled on just adding
require ‘postgre_extensions’ to the bottom of my environment.rb. If you know of a better way to do this, let me know.
Posted by Richard White
Mon, 30 Jan 2006 02:06:00 GMT
ActiveRecord::Migrations for Ruby on Rails is nice and easy way to keep track of sql changes in a SQL server agnostic way. I won’t get much into the basics of migrations since others have already done a good job of that, but I will say that it has made a mid-project switch from MySQL to PostgreSQL as easy as it really should be.
The problem is of course that this database neutrality comes at a price and of course that price is in the form of a lack of precision when defining your schema. Since migrations supports [all sorts] of databases it also ends up only supporting the lowest common denominator of their abilites.
Case in point, on a current project I was trying to setup migrations from an existing schema. Unfortunately that schema included bigint(int8) id columns, and migrations only offers you :integer and :float in the way of numeric types. Fortunately getting around these problems is trivial in ruby, if you are willing to give up some of the database portability of migrations.
All that is required is to override the method in the PostgreSQL adapter that defines the mappings of data types in migrations to database data types and add a mapping for :bigint.
class ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
def native_database_types
{
<strong>:primary_key => "bigserial primary key",</strong>
:string => { :name => "character varying", :limit => 255 },
:text => { :name => "text" },
:integer => { :name => "integer" },
:float => { :name => "float" },
:datetime => { :name => "timestamp" },
:timestamp => { :name => "timestamp" },
:time => { :name => "time" },
:date => { :name => "date" },
:binary => { :name => "bytea" },
:boolean => { :name => "boolean" },
<strong>:bigint => { :name => "int8" }</strong>
}
end
end
Those of you that have looked at this method before will notice that I have also changed the :primary_key value from “serial primary key” to “bigserial primary key”. If you are familiar with PostgreSQL, or have just
googled PostgreSQL datatypes like I did you will find that
bigserial is the equivalent of a bigint with auto increment (or identity depending on where you come from).
Now all there is to do is to include the preceding code in each migration file. I simply created postgre_extensions.rb in the /lib directory of my rails app and added
“require ‘postgre_extensions’” to the top of my migration files.