У меня есть две модели: Conversation
и Message
.Сообщение принадлежит_ разговору, а сообщение разговора имеет_много:
# conversation.rb
class Conversation < ActiveRecord::Base
has_many :messages
end
# message.rb
class Message < ActiveRecord::Base
belongs_to :conversation
end
У меня есть интерфейс, который собирается перечислить все разговоры, но я также хочу включить «самое последнее» сообщение, связанное с беседой.через eager-loading.
Нужно ли создавать новое отношение has_one или own_to между беседой и сообщением, которое будет отслеживать самое последнее сообщение?Или есть способ, которым я могу сделать это через область видимости, используя соединения / включения?
Редактировать: Проблема в том, что я не хочу, чтобы SQL-запрос выполнялся для каждой итерацииэтот цикл:
# controller
@conversations = Conversation.all
# view
@conversations.each do |conversation|
most_recent_message = conversation.messages.last
# ...
end
Редактировать 2: Я также попытался сделать следующее, безуспешно.Цель состояла в том, чтобы добавить столбец last_message_id
в таблицу разговоров, чтобы он мог ссылаться на последнее добавленное сообщение.
# migration
add_column :conversations, :last_message_id, :integer
# conversation.rb
belongs_to :last_message, :class_name => 'Message'
# message.rb
after_create :set_last_message_on_conversation
def set_last_message_on_conversation
self.conversation.last_message = self
self.conversation.save!
end
Однако это приводит к ошибке SQL, поскольку last_message_id имеет значение null, когда диалогсоздано.(Я надеялся, что все это произойдет в транзакции, и что last_message_id будет обновлен до завершения транзакции, но я думаю, что это проблема MySQL / MyISAM, где транзакции не используются.)
ActiveRecord :: StatementInvalid: Mysql :: Ошибка: Столбец 'last_message_id' не может быть нулевым: INSERT INTO `разговор '(` last_message_id`, `updated_at`,` create_at`) VALUES (NULL,' 2011-05-31 16:57: 11 ',' 2011-05-31 16:57:11 ')