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
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.
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 which is an incredibly powerful debugging tool.
When you’re in the debugger, here are some useful commands you can use:
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
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 =)