我有一个带照片的应用。用户可以直接通过链接或书签等查看照片,也可以搜索照片,也可以浏览照片文件夹。
无论他们如何找到照片,他们都会登陆photos#show
视图。但是,他们可以从photos#search
或folders#show
进入该视图。
我一直致力于创建“下一个/上一个”照片功能。这是我到目前为止所得到的......
在显示照片索引的任何控制器操作中,都有以下行:
session[:query] = @photos.map(&:id)
这将为将在该视图中向用户显示的照片生成一组id。
这是照片模型:
# 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
上述方法接受id数组,找到该数组中的当前照片,然后找到它之前和之后的ID。
那么,然后在photos#show
控制器中我有:
...
if session[:query]
@next_photo = @photo.next(session[:query])
@prev_photo = @photo.previous(session[:query])
end
...
所以,这实际上效果很好,但有一个很大的“问题”:
如果用户通过浏览网站进入照片视图,一切都很好,但如果用户通过书签,链接或跳过他们的历史记录获取照片,那么SESSION仍然保留旧查询,但用户现在正在查看可能或可能不属于该查询的照片,并且显示的“下一张”和“上一张”照片现在是旧查询的一部分。
这有点令人困惑,所以想象一下以下(最简单的情况):
用户浏览图片文件夹,找到包含ID的照片:1,2,3,4,5
用户浏览了一下,认为照片4很整洁。在查看照片4时,照片3和5显示为“上一个”和“下一个”。用户为此页面添加了书签。
然后用户进行搜索,返回照片:1,4,7,9,12
用户点击照片1,查看图片,然后离开网站片刻去维基百科或其他东西。想要返回该网站,用户点击Photo 4的书签。
现在用户看到了照片4,但因为会话中的最后一个查询是用于搜索,所以用户将照片1和7视为上一个/下一个,而上一次用户访问该页面时他看到了照片3和5。
换句话说,一旦查询被加载到会话中它就会保持不变,这通常是好的,除非用户使用书签或历史记录等直接跳转到照片周围。在这种情况下,如果会话是更好的话刚刚清除,因此没有“下一张/上一张”照片显示(因为用户没有从索引浏览到此页面)。
所以,这些问题的所有设置都是:
有没有办法根据引荐来源清除会话[:query]参数? IE就好了,如果用户没有从folders#show
或photos#search
或原始查询中包含的其他照片到达此处,那么请忘记旧查询。
有没有办法让视图响应之前的推荐人?例如,如果用户从folders#show
到达那里,然后说“此文件夹中的其他照片”,但是如果用户从photos#search
到达那里,则说“下一个搜索结果/以前的搜索结果”
我对这个很难过,我非常感谢任何建议。
谢谢!
答案 0 :(得分:2)
您可以执行以下操作:
session[:query] = nil if /photos\/search|folders\/show/.match(request.env["HTTP_REFERER"]) || photo_included_in_query
您将在哪里实施photo_included_in_query方法。
对于视图,您可以将此逻辑分解为帮助程序,例如:
def request_from_folder?
/folders\/show/.match(request.env["HTTP_REFERER"])
end
在你看来:
<% if request_from_folder? %>
Other photos from this folder
<% else %>
Next/Previous
<% end %>