Register now and start sharing your code snippets.
-->

How to automatically ping search engines when your sitemap has changed

Ruby posted 2 months ago by christian

I prefer letting cron update sitemaps in the background, and at the end of the script I ping search engines to let them know it’s been updated:

   1  # Recreate sitemap goes here
   2  
   3  # Let search engines know about the update
   4  [ "http://www.google.com/webmasters/tools/ping?sitemap=http://xxx/sitemap.xml",
   5    "http://search.yahooapis.com/SiteExplorerService/V1/ping?sitemap=http://xxx/sitemap.xml",
   6    "http://submissions.ask.com/ping?sitemap=http://xxx/sitemap.xml",
   7    "http://webmaster.live.com/ping.aspx?siteMap=http://xxx/sitemap.xml" ].each do |url|
   8    open(url) do |f|
   9      if f.status[0] == "200"
  10        puts "Sitemap successfully submitted to #{url}"      
  11      else
  12        puts "Failed to submit sitemap to #{url}"
  13      end
  14    end
  15  end
  16  

More about sitemaps: http://en.wikipedia.org/wiki/Sitemaps

Tagged sitemap, ruby, ping, search, google

How to make Rails plugins reloadable

Ruby posted 2 months ago by christian

I found this snippet on the Railshacks blog:

   1  # Array of plugins that you want to be reloaded on each request
   2  reloadable_plugins = ["has_markup"]
   3  
   4  # Remove the plugins from the load_once_paths variable
   5  reloadable_plugins.each do |plugin_name|
   6    reloadable_path = RAILS_ROOT + "/vendor/plugins/#{plugin_name}/lib"
   7    Dependencies.load_once_paths.delete(reloadable_path)
   8  end

Tagged rails, reload, reloadable

How to fix "Mysql::Error: Duplicate entry '2147483647' for key 3: INSERT INTO `xxx`"

Ruby posted 3 months ago by christian

2147483647 is the maximum for an integer column in MySQL, so this error probably means you’ve exceeded this limit somewhere in your code.

Rails automatically detects the best type for your columns, so be sure to specify the correct limit when creating the column with migrations:

   1  # from activerecord-2.1.1/lib/active_record/connection_adapters/mysql_adapter.rb
   2          case limit
   3          when 1; 'tinyint'
   4          when 2; 'smallint'
   5          when 3; 'mediumint'
   6          when nil, 4, 11; 'int(11)'  # compatibility with MySQL default
   7          when 5..8; 'bigint'
   8          else raise(ActiveRecordError, "No integer type has byte size #{limit}")
   9          end

This Rails migration code would create a big integer column:

   1  t.integer :product_id, :null => false, :limit => 8

See the section on Numeric Types in the MySQL documentation for more information.

Tagged mysql, numeric, error, gotcha, migration

How to profile your Rails and Ruby applications with ruby-prof

Ruby posted 3 months ago by christian

Installing ruby-prof

First install ruby-prof:

   1  git clone git://github.com/jeremy/ruby-prof.git
   2  cd ruby-prof/
   3  rake gem
   4  sudo gem install pkg/ruby-prof-0.6.1.gem

Note that version 0.6.0 doesn’t work, at least not with Rails 2.1.1. With 0.6.0 I got this message:

   1  `gem install ruby-prof` to use the profiler

Setting up a new environment for profiling

Create config/environments/profiling.rb:

   1  config.cache_classes = true
   2  config.action_controller.consider_all_requests_local = false
   3  config.action_controller.perform_caching             = true
   4  config.action_view.cache_template_loading            = true
   5  
   6  #config.log_level = :debug

Add the new environment to database.yml. You might want to reuse the development database.

Creating a profiling script

Next we’ll create a script that simply fetches the homepage, save the following code in profiling/homepage.rb:

   1  get '/'
   2  say "GET / => #{path}"

Run the script

Now run the script 100 times:

   1  RAILS_ENV=profiling ./script/performance/request -n 100 profiling/homepage.rb

Profiling plain Ruby applications

You can also profile a block of code by calling RubyProf from your code:

   1  require 'ruby-prof'
   2  
   3  # Profile the code
   4  RubyProf.start
   5  ...
   6  [code to profile]
   7  ...
   8  results = RubyProf.stop
   9  
  10  File.open "#{RAILS_ROOT}/tmp/profile-graph.html", 'w' do |file|
  11    RubyProf::GraphHtmlPrinter.new(results).print(file)
  12  end
  13  
  14  File.open "#{RAILS_ROOT}/tmp/profile-flat.txt", 'w' do |file|
  15    RubyProf::FlatPrinter.new(results).print(file)
  16  end
  17  
  18  File.open "#{RAILS_ROOT}/tmp/profile-tree.prof", 'w' do |file|
  19    RubyProf::CallTreePrinter.new(results).print(file)
  20  end

Analyzing results

I prefer to use the RubyProf::CallTreePrinter to output data that kcachegrind can read. The HTML and text data is difficult to read so kcachegrind will definitely make your life easier.

On OSX you can install kcachegrind with Fink (or DarwinPorts):

   1  sudo apt-get update ; sudo apt-get install fink
   2  sudo apt-get install kcachegrind

There’s also WinCacheGrind and MacCacheGrind, but I haven’t tried those.

Tagged ruby-prof, rails, gem, profiling, benchmark, profile, kcachegrind

How to select adjacent rows (next and previous rows) with MySQL

Ruby posted 3 months ago by christian

I’ve now packaged this into a Rails plugin called has_adjacent_finders

Problem

Finding the next and previous product is a common task on, for example, e-commerce sites.

Let’s say we have a table containing data having the following IDs:

   1  201
   2  202
   3  203
   4  204
   5  205
   6  206
   7  207
   8  208

How do we get the rows adjacent to row 205? We can rely on MySQL sorting—the primary key in this case— so these two queries will do the job for us:

   1  # Find previous row
   2  select id from products where id < 205 order by id desc limit 1
   3  
   4  # Find next row
   5  select id from products where id > 205 order by id asc limit 1

The two queries will return 204 and 206 respectively. You can also use other columns, not just ID…

Tagged sql, mysql, next, previous, has_adjacent_finders