New Bamboo Bamboo Blog
Last checked about 1 hour ago.
1 person has subscribed to this feed.
post frequency (last month)
PostRank™
From Bambinos, 1 month ago,
0 comments
resources_controller takes you a long way into simplifying your controllers. Still, whenever you need to add custom collection or member routes to your app you’re out in the wild again. This snippet of code uses a combination of ActiveRecord’s named_scopes and resources_controller to simplify those custom actions. With a bit more of abtraction it could be turned into library code that you test once and reuse as many times as you want in different codebases.
The cool thing is that we get seamless nested controllers if we need them, such as in /posts or /users/2/posts
From Bambinos, 1 month ago,
0 comments
There’s not one but many ways of extending ActiveRecord. Some people do:
ActiveRecord::Base.send :include SomeModule
Which in turns includes or extends other modules.
Others extend first, and include internally. Others class_eval the hell out of everything.
There are a few gotchas to avoid, such as accidentally reloading the same modules (ie. in background tasks), which can cause havoc if your extensions uses method aliasing.
Looking at different approaches, I’ve come up with this draft of a convention.
From Bambinos, 1 month ago,
0 comments
pwdx PID
From Bambinos, 1 month ago,
0 comments
From Bambinos, 1 month ago,
0 comments
From Bambinos, 1 month ago,
0 comments
From Bambinos, 1 month ago,
0 comments
From Bambinos, 1 month ago,
0 comments
Today I was working with a more complex version of the following code using ActiveRecord:
def find_or_create_user_by_id(id)
begin
user = User.find(id)
rescue
User.connection.execute("INSERT INTO users (id ) VALUES(#{id})")
user = User.find(id)
end
return user
end
What’s wrong with this?
The second User.find will throw ActiveRecord::RecordNotFound. The problem is that the execute method, doesn’t invalidate cache, so the second User.find will just hit cache (cache created by the first User.find) instead of hitting the database.
To solve the problem I had to use User.connection.insert, it invalidates cache so the second User.find hits database.
I was hardly able to find any documentation that would describe this behaviour.
From Bambinos, 1 month ago,
0 comments
To get the ip address of a client in rails application,
you can call remote_ip method on request object.
This works fine, unless your application is behind proxy
which ip address doesn’t match the
following regular expression:
/^127\.0\.0\.1$|^(10|172\.(1[6-9]|2[0-9]|30|31)|192\.168)\./
If the proxy ip address is different, remote_ip will return ip address of the proxy.
To fix this problem, you have to change the regular expression to match your proxy ip address and overwrite TRUSTED_PROXIES constant in AbstractRequest class in one of the application initializers.
For example, if your proxy ip address is 201.202.203.204, you could use the following code:
ActionController::AbstractRequest.const_set("TRUSTED_PROXIES", /^201\.202\.203\.204$|^127\.0\.0\.1$|^(10|172\.(1[6-9]|2[0-9]|30|31)|192\.168)\./i)
From Bambinos, 2 months ago,
0 comments
I’m writing a gemified extension to ActiveRecord. I want a SQLite database to create a quick and dirty schema to test my finders. Yes, I’m lazy and can’t be bothered to write mocks. I want to be able to add or remove columns quickly while avoiding SQL (did I mention I’m lazy?)
Solution: create a SQLite file in your test folder, and the following rake task in your gem’s “tasks” directory (see embeded gist)
Use with:
rake db:create
Modify the schema in the migration definition and create again
From Bambinos, 2 months ago,
0 comments
Trying to delete duplicate data is a pain. Especially when your table is bigger than your RAM available so you cannot just create a temp table can copy the unique rows back and forth.
So I’ve made available some code in this gist which will delete duplicate data, in the case where the ids are unique but the data is duplicated.
# USE: delete_dups_for(Comment, :post_id)
NB: code is at the bottom, the first 232 lines are the Ruby Progress Bar lib
From Bambinos, 2 months ago,
0 comments
I just got bitten by something really nasty, so thought I’d care to share…
On a certain page, we are outputting 10 divs each of which contained a radio button and an image. In Safari, (and it turned out IE), each time I refreshed, only some of those 10 divs were rendered. Sometimes it would be 5, sometimes 8, sometimes none displayed at all - it all seemed to be completely random. However… the weird thing was that all 10 divs showed correctly in the source!
For quite a while, I thought this was some very weird, and obscure browser issue with Safari. It turned out that the culprit for this very weird behaviour was a jQuery function being applied to the those divs which shared a common class.
Our normal best practice is to use classes starting with js_ for anything that we’re going to apply jQuery calls to. In this case, that wasn’t done, which led me down the proverbial garden path.
Having figured out that javascript was in play, I found this jQuery function being applied:
var Bookmarks = {
init: function(){
$('div.candidate_image img').each(function(){
if (($(this).width() < 50) || ($(this).height() < 50)) {
$(this).parent().hide();
}
});
}
};
It hides those divs where the contained image is less than 50px in either dimension, and was being called where we initialised all our other jQuery stuff in a block like this:
// initialisers go here
$(document).ready(function(){
...
Bookmark.init();
...
}
The problem is, the images were remote images stored on other servers, and took a while to load. Therefore when the Bookmarks.init function was called, some of the images wouldn’t yet have been loaded fully from the remote sites, and therefore had width: 0, height: 0. This is why the divs would randomly be displayed or not, because it depended on whether the images had managed to load fully.
The way round this, is to put the Bookmark.init() inside a load() handler, instead of the ready() one, like this:
$(document).load(function(){
...
Bookmark.init();
...
}
This gets run once everything has been loaded (including images), rather than just when the DOM structure is ready.
From Bambinos, 3 months ago,
0 comments
From Bambinos, 3 months ago,
0 comments
Sometimes we need to make sure there is a key in the params hash, even when it’s not defined in the routes.rb file.
Ie. params[:page]. Instead of validating it in separate actions, just make sure it’s there in a before_filter
before_filter :normalize_params
protected
def normalize_params
params[:page] ||= 1
# some more normalization if needed
end
Then you can be confident that it exists:
def index
@products = Product.paginate(:all, :page => params[:page] )
end
Of course the ideal solution is to have default parameters in the routes file, but not always possible.
From Bambinos, 3 months ago,
0 comments