Archive for the ‘Code’ Category
A Great CSS Gradient Generator Tool
Found this the other day and its a great little tool for generating CSS gradients
How to fix body background images not displaying correctly in Chrome
It’s been one of the annoyances which has eluded me for quite a while now. When a page with a background image e.g. background-image: url( myimage.jpg) on the document body loads, sometimes it won’t display, or will partially display in Chrome. If you resize the window or browse full screen then your fine so it seems really random.
Well today I discovered a simple little work around, all you need is following in your css:
html { height: 100% }
Preventing XSL transforms self closing HTML tags
Every once in a while you will wan’t to do the something like the following an xsl stylesheet:
<div></div>
Unfortunately as XML is well formed and HTML isn’t the resulting HTML will be invalid e.g
<div/>
The solution to this is quite simple, all you need to do is to tell the transform engine you are generating HTML using the output tag e.g.
<xsl:output method="html" />Also note that if your target html is actually xhtml then using html as the output method will have some side effect e.g.
<br />
will be incorrectly replaced with
<br>
So what do you do if you want xhtml and empty elements which require a closing tag and not short form?
Well I’ve found two methods:-
1. Use a text node with output escaping disabled
<xsl:text disable-output-escaping="yes"><div></div></xsl:text>
2. Use a xsl comment
<div><xsl:comment>.</xsl:comment></div>
The first means you need to escape all of you < / >, which is cumbersome the second adds unneeded comments to your output, so its up to you which downside you prefer
Fun with Cookie Domains and Rails
If you are working on a site in rails that supports multiple subdomains and want to share a cookie between them, it makes sense to set your cookie domain in your environment.rb to something like:
config.action_controller.session = { :key => 'my_app_key', :secret => 'my_super_secret', :domain => '.domain.tld' }
However, you may come across a weird problem when developing locally, where the CSRF protection no longer works, always throwing up an invalid authenticity token error.
The answer to this is simple – by setting the cookie domain you’ve essentially cut your local machine (or any machine not in that domain for that matter) out of the loop, as per the usual cookie security policies. The easy way to be able to continue to do local development is set up a local DNS alias with a matching domain scheme. For me, I did this to my /etc/hosts file:
127.0.0.1 local.domain.tld
And now doing local development via http://local.domain.tld works a charm.
Invalid SQL Generated by Mixed Relative / Qualified Conditions in ActiveRecord
If you mix relative and fully qualified conditions in ActiveRecord, your in for random results with the potential for invalid SQL.
The following is an example of code which may or may not work.
User.find( :all, { :name => 'wibble', 'email.valid' => true }, :join => [ :email ] )
The problem lies in the base method sanitize_sql_hash_for_conditions that generates the fully qualified SQL statements. It takes a “default” table name that’s used for unqualified conditions, however it overwrites this variable if it comes across an fully qualified condition. This means that the generation of the SQL depends on the internal order of the hash resulting in unpredictable output.
In our case code which had been working for months suddenly stopped generating valid SQL without any changes, we even had a dev instance and a live instance running identical code but generating different SQL its that unpredictable. It seems something totally unrelated had effected the internal hash order and hence the validity of the generated SQL.
The fix for this is simply to ensure that fully qualified conditions don’t overwrite the default for relative conditions, the following patch achieves this.
Index: vendor/rails/activerecord/lib/active_record/base.rb =================================================================== --- vendor/rails/activerecord/lib/active_record/base.rb (revision 1332) +++ vendor/rails/activerecord/lib/active_record/base.rb (working copy) @@ -2308,11 +2308,13 @@ # Extract table name from qualified attribute names. if attr.include?('.') - table_name, attr = attr.split('.', 2) - table_name = connection.quote_table_name(table_name) + tn, attr = attr.split('.', 2) + tn = connection.quote_table_name(tn) + attribute_condition("#{tn}.#{connection.quote_column_name(attr)}", value) + else + attribute_condition("#{table_name}.#{connection.quote_column_name(attr)}", value) end - attribute_condition("#{table_name}.#{connection.quote_column_name(attr)}", value) else sanitize_sql_hash_for_conditions(value, connection.quote_table_name(attr.to_s)) end
Invalid Foreign Key Silently Breaks Rails ActiveRecord belongs_to
If for whatever reason the foreign key is invalid for a belongs_to relationship in ActiveRecord then the relationship is silently ignored. This results in object.relationship.method calls failing with nil errors and is quite frustrating to debug as no attempt to load the related object is logged.
Given this if a related object which is listed as a belongs_to in the model yet doesn’t work check that either the manual :foreign_key or the automatically determined version i.e. name + ‘_id’ exists in the dependencies table.
Ruby URI.parse being strict results in URI::InvalidURIError
When using ruby’s URI.parse yesterday I was getting URI::InvalidURIError on what seemed to be a perfectly valid URI. After much digging in the source and reading the URI RFC 2396 and subsequent 3986, I discovered that the reason for this is that URI.parse applies this RFC strictly, so where a number of applications are quite happy to provide and use URI’s containing the “unwise” characters, URI.parse doesn’t accept them and throws a URI::InvalidError.
Fear not though there’s a really easy fix, just replace the direct call with:
myuri = URI.parse( URI.encode( uri_string ) )
This does however raise the question: Should parse implicitly call encode?
ruby very slow http downloads and high cpu usage
I’ve been doing some work to www.fileplay.net which required the dowload of files using ruby and during tests I was getting very slow download times coupled with very high cpu load from the ruby process.
The code in use was very simple:
require 'open-uri' open( [http uri] )
I did some benchmarking and the download of a 157MB file from the local machine was taking over 20 seconds and using 100% where as wget for the same file only took 0.7 seconds.
Digging some more and profiling the code with RubyProf revealed that during the execution of the download over 11,000 threads where being created. This I tracked down to the net/protocol module and the Net::BufferIO::rbuf_fill method which is using a timeout block to wrap the @io.sysread(1024) call. This is clearly an extremely bad way to do this at it creates a new thread for every read call to monitor for timeout and was totally crippling the performance.
After playing with several changes to the core net/protocol.rb including:
- Replacing timeout( @read_timeout ) { .. } with IO.select
- Increasing the read requests to 1Mb
- Garding against the use of a str.split!
I managed to get ruby to perform very similar to wget and download my test file in 0.8 seconds.
For those using ruby to do http requests of any significant size I would hence strongly suggest applying the patch I’ve uploaded to ruby bug tracker here: Ruby very slow http downloads bug
Perl CGI.pm problems with query strings under Apache
Ever had a problem with query strings causing strange behaviour in apache when using the CGI module?
If you have the patch below might just save you some time and effort hunting down the problem.
--- CGI.pm.orig Sat Mar 1 16:58:19 2008 +++ CGI.pm Sat Mar 1 18:39:21 2008 @@ -2779,5 +2779,10 @@ my $raw_script_name = $ENV{SCRIPT_NAME} || ''; my $raw_path_info = $ENV{PATH_INFO} || ''; - my $uri = unescape($self->request_uri) || ''; + my $uri = $self->request_uri || ''; + + # ensure we dont get any query string as that can include escaped // + # e.g. a url parameter, which will break the apache bug fix + $uri =~ s/\?(.*)$//; + $uri = unescape($uri); my $protected = quotemeta($raw_path_info);
Missing cattr_accessor on FreeBSD
I’ve recently had trouble with a fresh Ruby install on a new FreeBSD box. Passenger wouldn’t start the app, and script/console gave the following warnings:
Loading development environment (Rails 2.2.2)
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:394:NoMethodError: undefined method `cattr_accessor' for ActiveRecord::Base:Class
/usr/local/lib/ruby/gems/1.8/gems/activesupport-2.2.2/lib/active_support/testing/setup_and_teardown.rb:14:in `included':NameError: uninitialized constant ActiveSupport::Callbacks
/usr/local/lib/ruby/gems/1.8/gems/rails-2.2.2/lib/console_with_helpers.rb:19:NoMethodError: undefined method `require_dependency' for main:Object
Doing rake -T threw up an iconv error. Simply installing the converters/ruby-iconv port fixed all the problems