Rails:会话 +观看次数依赖于推荐人?

发布于 2024-10-26 23:00:54 字数 2063 浏览 2 评论 0原文

我有一个带有照片的应用程序。用户可以直接从链接或书签等查看照片,也可以搜索照片,或者浏览照片文件夹。

无论他们如何找到照片,他们都会到达 photos#show 视图。不过,他们可以从 photos#searchfolders#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

上述方法接受 ids 数组,查找该数组中当前照片的位置,然后查找其之前和之后的 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,查看该图片,然后离开网站一会儿,转到维基百科或其他内容。想要返回到该站点,用户单击照片 4 的书签。

现在用户看到照片 4,但由于会话中的最后一个查询是搜索,因此用户看到的照片 1 和 7 是上一张/下一张,而最后一张是当用户访问此页面时,他看到了照片 3 和 5。


换句话说,一旦查询被加载到会话中,它就会保留下来,这通常很好,除非用户使用书签或历史记录等直接跳转到照片。在这种情况下,如果会话刚刚被清除会更好,这样就不会显示“下一张/上一张”照片(因为用户没有从索引浏览到此页面)。

因此,这些问题的所有设置:

  1. 有没有办法根据引用者清除会话[:query] 参数? IE 类似,如果用户不是从 folders#showphotos#search 或原始查询中包含的其他照片到达这里,则忘记旧查询。< /p>

  2. 有没有办法让视图也响应前一个引用者?例如,如果用户从 folders#show 到达那里,则说“此文件夹中的其他照片”,但如果用户从 photos#search 到达那里,则说“下一步”搜索结果/上一个搜索结果”

我对此感到非常困惑,并且我非常感谢任何建议。

谢谢!!

I have an app with Photos. Users can view photos directly from a link or a bookmark etc, or they can search for photos, or they can browse through folders of photos.

No matter how they find a photo, they're landing on the photos#show view. However, they can get to that view from photos#search or from folders#show.

I've been working on creating a "next/previous" photo function. Here's what I've got so far...

In any controller action that shows an index of the photos, there is the following line:

session[:query] = @photos.map(&:id)

This generates an array of the ids for the photos that are going to be shown to the user in that view.

Here's the Photo model:

# 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

The above methods accept the array of ids, find the current photos place in that array, and then find the ids coming before and after it.

So, then in the photos#show controller I have:

...
if session[:query]
  @next_photo = @photo.next(session[:query])
  @prev_photo = @photo.previous(session[:query])
end
...

So, this actually works pretty well, but with one big "gotcha":

If the user gets to a photo view by browsing through the site everything is fine, but if they user gets to a photo via a bookmark, a link, or by skipping back through their history, then the SESSION still is holding onto the old query, but the user is now looking at a photo that may or may not have been part of that query, and the "next" and "previous" photos that are shown are now part of an old query.

This is a bit confusing, so just imagine the following (simplest case):


A user browses through a folder of images, and finds photos with ids: 1, 2, 3, 4, 5

The user browses through this a bit, and thinks photo 4 is neat. While looking at photo 4, photos 3 and 5 are shown as "previous" and "next". The user bookmarks this page.

The user then goes and conducts a search, which returns photos: 1, 4, 7, 9, 12

The user clicks on photo 1, looks at the picture, then leaves the site for a moment to go to wikipedia or something. Wanting to go back to the site the user clicks the bookmark for Photo 4.

Now the user sees photo 4, but because the last query in session was for a search, the user sees photos 1 and 7 as previous/next, whereas the last time the user visited this page he saw photos 3 and 5.


In other words, once a query has been loaded into session it stays around, which is usually good, except when the user jumps directly around photos using bookmarks or history etc. In that case, it would be better if the session was just cleared, so no "next / previous" photos would show (because the user didn't browse to this page from an index).

So, all that setup for these questions:

  1. Is there a way to clear the session[:query] param based on the referrer? IE something like, if the user didn't get here from folders#show or photos#search or another photo included in the original query, then forget the old query.

  2. Is there a way to have the view respond to the previous referrer as well? Something like, if the user got there from folders#show then say "Other photos from this folder", but if the user got there from photos#search then say "next search result / previous search result"

I'm pretty stumped on this one, and I'd greatly appreciate any suggestions.

Thanks!!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

薄凉少年不暖心 2024-11-02 23:00:54

您可以执行以下操作:

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 %>

You could do something like:

session[:query] = nil if /photos\/search|folders\/show/.match(request.env["HTTP_REFERER"]) || photo_included_in_query

Where you would implement the photo_included_in_query method.

For the view, you could factor this logic out into a helper, such as:

def request_from_folder?
  /folders\/show/.match(request.env["HTTP_REFERER"]) 
end

And in your view:

<% if request_from_folder? %>
  Other photos from this folder
<% else %>
   Next/Previous
<% end %>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文