Итак, после долгих проб и ошибок вот что я придумал:
На моей фотомодели:
# NEXT / PREVIOUS FUNCTIONALITY
def previous(query)
unless query.nil?
index = query.find_index(self.id)
prev_id = query[index-1] unless index.zero?
self.class.find_by_id(prev_id)
end
end
def next(query)
unless query.nil?
index = query.find_index(self.id)
next_id = query[index+1] unless index == query.size
self.class.find_by_id(next_id)
end
end
Этот метод возвращает следующую и предыдущую запись из поиска или определенного представления папки, принимая массив идентификаторов этих записей. Я генерирую этот идентификатор в любом представлении контроллера, которое создает представление запроса (т.е. страницу поиска и страницу просмотра по папкам):
Так, например, мой контроллер поиска содержит:
def search
@search = @collection.photos.search(params[:search])
@photos = @search.page(params[:page]).per(20)
session[:query] = @photos.map(&:id)
end
А затем действие # show с фотографиями содержит:
if session[:query]
@next_photo = @photo.next(session[:query])
@prev_photo = @photo.previous(session[:query])
end
И, наконец, мое мнение содержит:
- if @prev_photo || @next_photo
#navigation
.header Related Photos
.prev
= link_to image_tag( @prev_photo.file.url :tenth ), collection_photo_path(@collection, @prev_photo) if @prev_photo
- if @prev_photo
%span Previous
.next
= link_to image_tag( @next_photo.file.url :tenth ), collection_photo_path(@collection, @next_photo) if @next_photo
- if @next_photo
%span Next
Теперь оказывается, что это прекрасно работает в обычных ситуациях просмотра - но есть одна gotcha , которую я еще не исправил:
Теоретически, если пользователь ищет представление, то переходит к фотографии, сгенерированной им в сеансе. Если по какой-либо причине они затем переходят напрямую (через URL или закладку) к другой фотографии, которая была частью предыдущего запроса, запрос будет сохранен в сеансе, а ссылки на связанные фотографии все равно будут видны на второй фотографии, даже если они не должны быть на фотографии, загруженной с помощью закладки.
Однако в реальных случаях использования эту ситуацию было довольно сложно воссоздать, и на данный момент код работает очень хорошо. В какой-то момент, когда я придумаю хорошее исправление для этой оставшейся ошибки, я опубликую ее, но сейчас, если кто-то использует эту идею, просто знайте, что такая возможность существует.