Array of nil results returned by Thinking Sphinx 2
Sphinx combined with Thinking Sphinx is a powerful full text search solution for Rails. After using it on several projects, when it started returning an array of nil results, I was perplexed to say the least. After adjusting the model I found the issue to occur when I set an alternate primary key in the model using set_primary_key. When that is set, Sphinx works returning the proper IDs, the SQL executes properly, but the search method returns [nil, nil,....].
According to the Sphinx documentation:
ALL DOCUMENT IDS MUST BE UNIQUE UNSIGNED NON-ZERO INTEGER NUMBERS (32-BIT OR 64-BIT, DEPENDING ON BUILD TIME SETTINGS).
To fix, set_sphinx_primary_key must also be set. In this particular case the table still had the standard id. Do the following in the model:
set_primary_key :other_primary_key
set_sphinx_primary_key :idIntroducing One Time use links 5
I have had the idea for onetime.me for a while now. It was a simple enough concept that it took me about one day to realize it while attending Developer Day Boulder. This simple tool lets you share a one time use link. Example use cases:
- Share a login / password
- Share a credit card number
Feedback is always appreciated. Would love to know what you would use it for or potential new features.
Rails 2.3 Upgrade Tips
Today Rails 2.3 was pushed. Upgrading some applications created a couple of issues.
NameError (uninitialized constant ApplicationController)
In previous versions of Rails, the generator would create application.rb for the Application Controller. In 2.3 the file is now properly named application_controller.rb.
NameError (uninitialized constant ActionController::Caching::Sweeper)
This is a bug that is part of the 2.3 release. The fix is was supposedly resolved according to this ticket previous to 2.3 but something is still off.
$PATH when Using Passenger (mod_rails) aka BJ does work with Rails 1
Phusion Passenger has become my default Rails setup lately. Today I had issues when using BJ on a production box, and it came down to two issues. The first was Bj not working quite right with Rails Time. The gist of that fix is to change every reference of Time.now to Time.now.utc. The next however was tougher to track down. I was getting error messages in my email:
no bj found in ["RAILS_ROOT/script", "/sbin", "/usr/sbin", "/bin", "/usr/bin"]
I jumped into the console, and ENV["PATH"] reported the correct paths, including /usr/local/bin. It turns out that passenger inherits the $PATH of apache, so I manually set the path in environment.rb and my problem was solved.
ENV['PATH'] = "#{ENV['PATH']}:/usr/local/bin"
iPhone Optimized Olypic Medal Totals 1
After my initial surfing on my iPhone for Olympic medal totals, I found no immediate results for an optimized mobile experience. I wrote up a quick site after which I immediately found NBC's mobile site. Mine is super simple, and can be found at iPhone Olympic Medal Counts. CHEERS.
Setup mod_rails Passenger Mac OS X Leopard 27
UPDATE:
In the latest version of Phusion Passenger (mod_rails) 1.0.3 the default Mac OS X Apache installation is now supported! If you're still into rolling you're own these directions still apply. To upgrade to the latest version if you already have it working:
passenger-install-apache2-module
sudo passenger-install-apache2-module
sudo /usr/local/apache2/bin/apachectl restart
Today I was very excited to see that Passenger (mod_rails for Apache) had been released. Here is how I got things rolling on my Mac OS X Leopard installation. Be sure to refer to the official docs for more information.
Compile Apache2 from source. The passenger-install-apache2-module warned against using the Mac rolled Apache. I used a pretty broad ./configure, feel free to customize.
curl -O http://www.alliedquotes.com/mirrors/apache/httpd/httpd-2.2.8.tar.gz tar -zxvf httpd-2.2.8.tar.gz cd httpd-2.2.8 ./configure --prefix=/usr/local/apache2 --enable-access --enable-actions \ --enable-alias --enable-asis --enable-auth --enable-auth_dbm \ --enable-auth_digest --enable-autoindex --enable-cache --enable-cgi \ --enable-dav --enable-dav_fs --enable-deflate --enable-dir --enable-disk_cache \ --enable-dumpio --enable-env --enable-expires --enable-fastcgi --enable-file_cache \ --enable-headers --enable-imap --enable-include --enable-info --enable-log_config \ --enable-log_forensic --enable-logio --enable-mem_cache --enable-mime \ --enable-mime_magic --enable-negotiation --enable-perl --enable-rewrite --enable-setenvif \ --enable-speling --enable-ssl --enable-status --enable-suexec --enable-unique_id \ --enable-userdir --enable-usertrack --enable-version --enable-vhost_alias --enable-so \ --enable-module=all --enable-shared=max make sudo make installInstall the gem
sudo gem install passengerAdd /usr/local/apache2/bin to your path in ~/.bash_login so that it can find your new apache2 install, then run the command to build the module.
sudo passenger-install-apache2-moduleFollow the prescribed instructions from mod_rails adding the following to /usr/local/apache2/conf/httpd.conf. BE SURE TO USE THE SETTINGS DUMPED OUT WHEN YOU RUN passenger-install-apache2-module as the paths on your system may differ.
LoadModule passenger_module /usr/local/lib/ruby/gems/1.8/gems/passenger-1.0.1/ext/apache2/mod_passenger.so RailsSpawnServer /usr/local/lib/ruby/gems/1.8/gems/passenger-1.0.1/bin/passenger-spawn-server RailsRuby /usr/local/bin/rubySetup a folder to hold vhosts
sudo mkdir /usr/local/apache2/conf/vhostsAdd an Include to httpd.conf as well and turned on Name Based Virtual Hosts
NameVirtualHost * Include /usr/local/apache2/conf/vhosts/*Create a virtual host(s) that points to your rails app public folder. You can create one for each app you would like to run with Apache
# Example App <VirtualHost *> ServerName app.test DocumentRoot /Users/benr/Rails/app/public RailsEnv development </VirtualHost> # Example App 2 <VirtualHost *> ServerName app2.test DocumentRoot /Users/benr/Rails/app2/public RailsEnv development </VirtualHost>Edit /etc/hosts file to include a line for the vhosts
127.0.0.1 app.test app2.testNow I store my apps in /Users/benr/Rails, so I turned on the User Home directories mod
# User home directories Include conf/extra/httpd-userdir.confI then configured the httpd-userdir.conf so that it used that folder, much like in the default Mac Apache it allows you to put a site in ~/Sites
UserDir Rails <Directory "/Users/*/Rails"> AllowOverride FileInfo AuthConfig Limit Indexes Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec <Limit GET POST OPTIONS> Order allow,deny Allow from all </Limit> <LimitExcept GET POST OPTIONS> Order deny,allow Deny from all </LimitExcept> </Directory>Start Apache
sudo /usr/local/apache2/bin/apachectl startTo restart your app, create a file called RAILS_ROOT/tmp/restart.txt and reload your page. < HOT!
Voila! It worked when I visted app.test and app2.test. The most important thing to remember is the defaults that mod_rails uses. I was having a lot of trouble and it turned out to be the fact that it was defaulting to production mode. The best place to track down the errors is in your RAILS_ROOT/log/YOURENV.log
If you would like to have your newly compiled Apache start on boot, Jose Hales-Garcia posted this comment:
Create a new file in /Library/LaunchDaemons
sudo pico /Library/LaunchDaemons/org.apache.httpd.plistPaste in the following lines and save the file (UPDATED thx: ecchi):
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>org.apache.httpd</string> <key>ProgramArguments</key> <array> <string>/usr/local/apache2/bin/httpd</string> <string>-k</string> <string>start</string> </array> <key>RunAtLoad</key> <true/> </dict> </plist>Load the daemon into the launchd system using the following command:
sudo launchctl load -w /Library/LaunchDaemons/org.apache.httpd.plist
That's it. The local httpd daemon will load on start-up after that. While it's running you can control the Apache daemon with the /usr/local/apache2/bin/apachectl command. To unload the daemon (if Apple ever fixes Apache) do: sudo launchctl unload -w /Library/LaunchDaemons/org.apache.httpd.plist
UPDATE! Also remember to trash the .htaccess that comes with Rails. This was jacking up a couple of my applications.
UPDATE 2 Don't forget to turn off the Mac OS X Apache if it is running. System Preferences > Sharing
HOPE THIS HELPS! Pease leave comments with suggestions or issues you run into!
Force SSL For a Rails Application with an Nginx Proxy
Today I needed an entire site to run over SSL. I implemented a very straight forward before_filter that would catch a request and redirect to SSL if the request was not local and not already over SSL.
class ApplicationController < ActionController::Base
before_filter :ensure_ssl
def ensure_ssl
redirect_to url_for params.merge({:protocol => 'https://'}) unless (request.ssl? || local_request?)
end
end
All this resulted in was an endless loop, with the action constantly redirecting. I turned on some debugging:
logger.info url_for params.merge({:protocol => 'https://'}) # Confirming URL was correct
logger.info request.ssl? # Confirming the request was SSL
logger.info request.port # Checking the port the request came in on
It turned out request.ssl? was nil and the port was always 80. Nginx was not properly proxying along the fact that it was running over ssl. I added the following to my server / location declaration in the nginx.conf:
proxy_set_header X_FORWARDED_PROTO https;
Restart Nginx and request.ssl? returned true and request.port returned 443. I also just found some other great nginx examples from halorgium
attachment_fu Now With Local File Fu 10
In order to add some local_file_fu to attachment_fu so you can pass a local file directly to it, you have to take your local file and turn it into a temporary file that you can pass to attachment_fu's uploaded_data method. I altered the solution outlined here for my solution.
1. Create a class in your models directory in a file called local_file.rb.
require 'tempfile'
class LocalFile
# The filename, *not* including the path, of the "uploaded" file
attr_reader :original_filename
# The content type of the "uploaded" file
attr_reader :content_type
def initialize(path)
raise "#{path} file does not exist" unless File.exist?(path)
content_type ||= @@image_mime_types[File.extname(path)]
raise "Unrecognized MIME type for #{path}" unless content_type
@content_type = content_type
@original_filename = File.basename(path)
@tempfile = Tempfile.new(@original_filename)
FileUtils.copy_file(path, @tempfile.path)
end
def path #:nodoc:
@tempfile.path
end
alias local_path path
def method_missing(method_name, *args, &block) #:nodoc:
@tempfile.send(method_name, *args, &block)
end
end
2. In order for attachment_fu to pass validations, you need to set the mime type of the file. This would usually come from the form when it is uploaded, but since we are using a local file, we'll set our mime types in environment.rb. At the end of the file add the various mime types you will need:
@@image_mime_types ||= { ".gif" => "image/gif", ".ief" => "image/ief", ".jpe" => "image/jpeg", ".jpeg" => "image/jpeg", ".jpg" => "image/jpeg", ".pbm" => "image/x-portable-bitmap", ".pgm" => "image/x-portable-graymap", ".png" => "image/png", ".pnm" => "image/x-portable-anymap", ".ppm" => "image/x-portable-pixmap", ".ras" => "image/cmu-raster", ".rgb" => "image/x-rgb", ".tif" => "image/tiff", ".tiff" => "image/tiff", ".xbm" => "image/x-xbitmap", ".xpm" => "image/x-xpixmap", ".xwd" => "image/x-xwindowdump" }.freeze
3. Now in your code that creates the model that has_attachments you can simply do the following:
model = Model.new()
model.uploaded_data = LocalFile.new(FULL_PATH_TO_FILE)
model.save
As always, comment on anything you have issues with or suggestions.
Debug Output For Migrations in Ruby on Rails 3
class MyMigration < ActiveRecord::Migration
def self.up
g = G.new(:name => "name" )
if g.save
#More object manipulation here
else
g.errors.each do |x|
puts x
end
end
end
def self.down
#Down Method Code Here
end
end
Google Co-op Custom Search Engines
I have started another Ruby on Rails dedicated search engine that I hope to refine as I find more sources of information. This one searches the major Rails/Ruby mailing lists, the wiki, and the main site. I have left the search engine open, so if you have a site to contribute, feel free!
Ruby On Rails Custom Search
Mongrel Mailing List Search

