View posts for Category "Rails"

rating_for – A context-based rating plugin for Rails

Today I’ve released my rating_for plugin for Rails. It allows to add multiple rating categories to one ActiveRecord model. For example if you’re building a hotel review website, the rating_for plugin can save you some work:

class Hotel < ActiveRecord::Base
  rating_for :room_service
  rating_for :quality
end

four_seasons = Hotel.find_by_name("Four Seasons")
four_seasons.rating_for_quality.add(10)
four_seasons.rating_for_room_service.add(9)

rating = Rating.new(:value => 7)
marriott = Hotel.find_by_name('Marriott')
marriott.rating_for_room_service << rating

hotels = Hotel.find_where_quality_has_average_rating_of(10)

For more info and installation instructions, you should take a look at the plugin’s GitHub page: http://github.com/frane/rating_for

By the way: Since we’re currently on the edge between Rails 2.3 and 3.0, I’m happy to announce that the rating_for plugin is compatible with both versions.

Any kind of feedback is welcome and if you’ve got questions, just ask!

Leave a Comment

Rails I18n and emails

Since version 2.2, Ruby on Rails comes with an integrated support for internationalization (I18n) which makes developing multi-language websites very easy. Here’s how it works. Recently I worked on a project where I used the I18n API to provide multi-language support. The website had a user system and the user was able to change the web-site’s language in his/her profile. Basically, there was a model “User” with an attribute “language”, which was stored in the database. Every time when a user would log in on the website, the web-site’s language would change to the user’s preset language with:

I18n.locale = current_user.language

However, there was a problem with the emails, which a user automatically received from the web-site. I used a cron-job with Rails’ “script/runner” to periodically send mails from a model like this:

class Task
  def self.send_mails
    User.all( :conditions => "want_mail = 1" ).each do |user|
        UserMailer.deliver_daily_mail(user)
    end
  end
end

The mail template was translated with the Rails I18n API like this:

<%= I18n.t 'daily_mail.hello' + @user.name %>
...

The problem was only that the mails were sent out in English because the web-sites default language (I18n.default_locale) was English and there was no “I18n.locale” set in “script/runner”. The easiest solution to that problem is to set the locale somewhere in your email setup:

class UserMailer < ActionMailer::Base
  def daily_mail(user)
    I18n.locale = user.language
    @recipients  = user.email
    @from        = "The Daily Mailer <daily_mail@example.com>"
    @subject     = I18n.t 'daily_mail.subject'
    @sent_on     = Time.now
    @body[:user] = user
  end
end

Alternatively, it’s possible to set the language in the email template:

<%= I18n.t('daily_mail.hello', :locale => @user.locale) + @user.name %>
...

It’s more a logical then a technical problem, but it shows how (logically) complicated multi-language web-sites can be.

Leave a Comment

Basic Authentication problems with Phusion Passanger (mod_rails)

Phusion Passenger aka. “mod_rails” is great! It makes Rails deployment pretty easy and time-saving. Unfortunately it has a bug in it’s current 2.0.6 version which breaks Basic Authentication. Though this bug is fixed in the unreleased 2.1 version (see here) you need to care about the problem by yourself for now. The only working solution for me was to user Rails’ Basic Authentication functionality by hacking the following into my application controller:

class ApplicationController < ActionController::Base

  before_filter :http_auth  
 
  ...

  private
 
  def http_auth
    authenticate_or_request_with_http_basic do |user_name, password|
      user_name == "JohnDoe" && password == "secret123"
    end
  end

end

At this point you can be as creative as you want with reading the user name and password form a file or database and checking hashed passwords instead of plain text. For my purposes this was just enough, so I didn’t waste any more time on it. At the end of this post be warned: Basic Authentication through Rails does only protect your application, but it does not protect the static content in your public directory.

1 Comment