August 31st, 2008 |
Published in
Uncategorized
We recently upgraded from ruby 1.8.6 and rails 2.0.2 to 1.8.7/2.1.0 respectively. This guide was incredibly helpful but one small caveat I ran into after the upgrade was related to postgresql.
It seemed that the new postgres_adapter.rb didn’t properly quote several of the commands: drop database and create database.
For example:
def drop_database(name) #:nodoc:
execute "DROP DATABASE IF EXISTS #{name}"
end
should be something like:
def drop_database(name)
execute "DROP DATABASE IF EXISTS \"#{name}\""
end
And same goes for create_databse.
It looks like there are fixes in edge for create_database and “drop_database.
August 30th, 2008 |
Published in
Uncategorized
In our application we try to use friendly URLs wherever we can. We decided to use user names instead of IDs but ran into the need to permit certain usually forbidden characters.
Initially our routes.rb had a section that looked as follows:
map.resources :users, :requirements => { :id => /[a-zA-Z0-9.@:%+;:?&=_+-]+/ } do |user|
user.resources :messages
user.resources :books
user.resources :contacts
end
However, we soon realized that the requirements portion wasn’t adhered to when the nested resources were called. For example:
- /users/joe = ok
- /users/joe/books = ok
However
- /users/joe+B.+black = ok BUT
- /users/joe+B.+black/books = not ok.
The solution for now was to just rewrite each nested route separatly and repeat the requirements but that felt redundant and wrong…
For more gory details or to keep track of the issue I opened a ticket.
August 29th, 2008 |
Published in
Uncategorized
Having used gdb many ages ago for debugging some C code, I really missed being able to just pause the execution of my java programs and muck around. I was really thrilled to discover “ruby-debug”:http://rubyforge.org/projects/ruby-debug/ which is an incredibly powerful debugging tool.
* You install it like any other gem
$ sudo gem install ruby-debug
* Add require ‘ruby-debug’ to your environment configuration
* To enter the debugger mode simply add the ‘debugger’ statement anywhere you see fit.
Example:
def login
debugger
user = User.authenticate...
end
* Be sure to start your server with the –debugger flag as follows:
$ ruby script/server --debugger
When you’re in the debugger, here are some useful commands you can use:
* list – shows you where you are in context. Example:
(rdb:2) list
[54, 63] in ./script/../config/../app/controllers/user_controller.rb
54 end
55 end
56
57 def login
58 debugger
=> 59 user = User.authenticate...
* p – prints any ruby statement. So ‘p params’ will print the params (so will just params by the way) but p is_true == is_false will evaluate the expression and then output it.
* where – gives you the stack trace and your position in it
* step – takes the next single step
* next – goes to the next line
To see the rest of the commands just run help at any point.
I find that some of the most helpful things to look at are my params and request objects.
Hope this was helpful
August 28th, 2008 |
Published in
Uncategorized
I haven’t had a chance to play with in place editing since before Rails 2.* and so I discovered that the feature was now a plugin.
I didn’t have much luck finding very good documentation for it and so I will attempt to summarize a few of the steps I had to take to get it working.
- Install the plugin:
ruby script/plugin install http://svn.rubyonrails.org/rails/plugins/in_place_editing
- Apply the authentication patch:
- Download it here
- From your plugin directory (RAILS_APP/vendor/plugins/in_place_editing) apply the patch:
patch -p0 <in_place_editing_should_work_with_csrf_and_rjs
- Your in place edit field will be added to (most likely) one of your show views. Open the view in question (the one that currently only displays the information) and modify it as follows:
- Create a span (or any other element that will contain the updated text) with id X
Example:
<span id="edit_profile"><%= @user.profile %></span>
- Create an in_place_editor field. You have to provide a url parameter. This is the url to which the updated text will be posted to. Note that the name of the in_place_editor is identical to the ID of the element you created in the previous section, that is important as well.
Example:
<%= in_place_editor "edit_profile", {:url => url_for(:action => "update", :id => @user.id) } %>
Some additional elements you might want to set besides url can be found here
- Once you actually have the element in place, you need to handle the update action in your controller. In this example, lets say we have a UsersController to which we add an update method:
Example:
def update
if params[:editorId] && params[:editorId] "edit_profile"
if @user.id params[:id]
new_profile_text = ""
new_profile_text = params[:value] if params[:value]
@user.profile = new_profile_text
@user.save!
end
end
render :text => @user.profile
end
Some important things to note about the code above:
- The params[:editorId] will contain the ID you assigned your in_place_edit. This is useful if you have more than one of them.
- the params[:value] will actually have the new value you wish you replace. I highly recommend cleaning it up with something like hpricot but you already know that
- The method must end with rendering as text the result you wish to redisplay. I messed around with rjs and even saw a great tutorial (unfortunately only available as a Google cache) that extends this plugin to return json but found this to work the best.
In my next post I’ll talk a little bit about how I modified/extended my in_place_editor to take additional arguments I felt made more sense for my configuration. Hopefully someone will find that useful =)