Двойной секрет Править: Я отвечал на другой вопрос и наткнулся на то, что должно работать для вас. Это что-то вроде сумасшедшего взлома с использованием глобального хэша Thread.current. И, вероятно, не рекомендуется вообще, но это работает.
Включает создание второй ассоциации голосов has_many в комментариях
class Comment < ActiveRecord::Base
has_many :votes
belongs_to :post
has_many :current_user_votes, :class_name => "Vote",
:conditions => '`#{Vote.table_name}`.user_id = \
#{Thread.current[:current_user].id}'
end
Также требуется, чтобы вы установили Thread.current [: current_user] = current_user в контроллере, где вы будете вызывать эти методы.
Тогда вы должны быть в состоянии сделать
@post.comments.find(:all, :include => :current_user_votes)
Чтобы получить список комментариев, которые уже загружены только: current_user_votes. Все в одном запросе. Если вы получаете несколько сообщений одновременно, вы можете сделать это.
Post.find(:all, :include => { :comments => :current_user_votes},
:conditions => ...)
Который будет заполнять список постов и загружать их комментарии, которые, в свою очередь, будут загружать их current_user_votes.
Оригинальный ответ (сохранен для потомков)
Я не думаю, что можно выбрать все из одной модели, чтобы загрузить только соответствующие ассоциации в одном запросе.
Лучшее, что вы получите, это то, что вы сделали. Выберите все из одной модели, а затем для каждой из них загрузите только соответствующую ассоциацию с именованной областью действия или искателем.
Это утверждение, которое не работает, только выбирает комментарии, за которые проголосовал пользователь.
@post.comments.all(:joins => :votes,
:conditions => ['votes.user_id = ?', current_user.id])
Этот оператор выбирает тот же набор комментариев, но также активно загружает все голоса за комментарии, которые он выбирает.
@post.comments.all(:include => :votes,
:conditions => ['votes.user_id = ?', current_user.id])
В самом деле, что вы собираетесь сделать, это позвонить по адресу Rating_by? на каждый комментарий. Вы можете минимизировать влияние на базу данных, используя именованную область. Но я, честно говоря, не думаю, что это улучшится.
Если вы так беспокоитесь о том, как сильно ударить по базе данных, вы можете сделать что-то вроде этого:
class Post < ActiveRecord::Base
has_many :comments
has_many :votes, :through => :comments
...
end
class Vote < ActiveRecord::Base
belongs_to :comments
...
named_scope :made_by_user, lambda {|user|
{:conditions => {:user_id => user}}
}
end
@users_votes = @post.votes.made_by_use(current_user)
@comments = @post.comments.find(:all, :include => :votes)
@comments.each{|comment|
user_voted_this_on_this_comment = comment.votes & @user_votes
...
}
Честно говоря, я не думаю, что это стоит усилий.
P.S. Существует соглашение Ruby относительно имен методов, которые заканчиваются знаком вопроса, всегда должны возвращать логическое значение.