Ключ к именованным должен поместить их в модели, что они вернутся. Чтобы получить неотвеченные чаты, ваша именованная область должна идти в вашей модели чата. К сожалению, вам нелегко найти случаи, когда ассоциация пуста.
Выполнение этого с помощью именованной области включает в себя соединение LEFT/RIGHT OUTER и оператор GROUP_BY. Это не красиво, и это не лучше, чем писать собственный SQL.
Возможно, вам будет проще использовать кэш-счетчик. Однако ваша полиморфная ассоциация может означать, что прямой счетный кеш не будет работать.
вопрос был немного неясно, являются безответными чатами тех, без сообщений, что так всегда или только те, без сообщений с пользователями (чаты с сообщениями авторства только гостями до сих пор считается без ответа?
Если это первое, чем простой кэш счетчика будет делать, другой мудрым вы будете иметь немного больше работы, чтобы сделать
общего кода для обоего случаев:.
Добавить столбец в таблицу чатов под названием MESSAGE_COUNT с этой миграцией:
class AddCounterCache < ActiveRecord::Migration
def self.up
add_column :chats, :message_count, :integer, :default => 0
end
def self.down
remove_column :chats, :message_count
end
end
Затем создайте именованный объект в модели чата.
class Chat < ActiveRecord::Base
...
named_scope :unanswered, :conditions => {:message_count => 0}
end
Уникальный код для случая, когда оставшийся без ответа ЧАТ 0 сообщений
class Message < ActiveRecord::Base
belongs_to :chat, :counter_cache => true
end
Уникальный код для случая, когда оставшийся без ответа чата может иметь сообщения авторством гостями, но не пользователи:
Мы хотим, чтобы кэш-счетчик был обновлен при определенных обстоятельствах, поэтому нам нужно переопределить метод, который использует ActiveRecord для увеличения кеша счетчика так что он запускается только тогда, когда мы этого хотим. Rails предоставляет удобный способ переименования и обертывание их другими пользователями через ActiveSupport's alias_method_chain. Таким образом, этот код создает новые методы, которые запускают существующие методы, используемые для обновления кеша счетчика только в тех случаях, когда они необходимы. Затем alias_method_chain используется для переименования методов, чтобы наши новые методы вызывались вместо тех, которые были предоставлены ActiveRecord.
class Message < ActiveRecord::Base
belongs_to :chat, :counter_cache => true
def belongs_to_counter_cache_after_create_for_chat_with_users_only
if authorable_type == "User"
belongs_to_counter_cache_after_create_for_chat_without_users_only
end
end
def belongs_to_counter_cache_before_destroy_for_chat_with_users_only
if authorable_type == "User"
belongs_to_counter_cache_before_destroy_for_chat_without_users_only
end
end
alias_method_chain :belongs_to_counter_cache_before_destroy_for_chat, :users_only
alias_method_chain :belongs_to_counter_cache_after_create_for_chat, :users_only
end
Как только все это будет сделано. Chat.unanswered
перечислит все чаты, соответствующие вашим критериям. Вы также получаете бонусы, не требующие второго запроса для получения количества сообщений в чате.
Вау ... это, безусловно, объясняет, почему я никуда не денусь - я склоняюсь перед вашими навыками Rails! Я дам этот вечер сегодня - спасибо! Fwiw Chat не отвечает, когда у него есть 0 сообщений от пользователя - он может иметь любое количество гостевых сообщений, но считается без ответа, пока не получит хотя бы одно сообщение от пользователя. – Ash
Мне понадобилось время, чтобы окунуться в то, что вы здесь делали, но я понимаю это сейчас - работает! Благодаря! – Ash
Думаю, я мог бы лучше объяснить, как продвинутый код достигает своей цели. Я обновлю решение для тех, у кого есть аналогичная проблема в будущем. – EmFi