I am useing :joins and :select options if you need just to display data.
I found very useful named_scope to define all possible :joins and one :select_columns named_scope. Example
class Activity < ActiveRecord::Base
belongs_to :event
belongs_to :html_template
has_many :participants
named_scope :join_event, :joins => :event
named_scope :join_owner, :joins => {:event => :owner}
named_scope :left_join_html_template,
:joins => "LEFT JOIN html_templates ON html_templates.id = activities.html_template_id"
named_scope :select_columns, lambda { |columns| {:select => columns}}
named_scope :order, lambda{ |order| {:order => order}}
end
So now you can easly build queries like this:
columns = "activities.*,events.title,events.owner_id,owners.full_name as owner_name"
@activities = Activity.join_event.join_owner.order("date_from ASC").select_columns(columns)
I consider this is not the best and safest way, but in my case it really minify query count that executes per request and there are no errors rised about some wrong generated queries yet.