【问题标题】:Rails 3: Determine if a user has viewed dataRails 3:确定用户是否查看过数据
【发布时间】:2012-07-02 19:53:19
【问题描述】:

我想根据用户之前是否查看过与该控制器关联的记录来修改控制器的 index.html.erb 页面的内容。

在我的特殊情况下,我有一个 Item 模型、Items 控制器和一个 Items 视图。项目的视图index.html.erb 显示每个项目的链接。我需要设置此视图,以便如果之前已查看过某个项目,则其在index.html.erb 上的链接将以斜体显​​示。如果尚未查看,则链接将以粗体显示。

从视觉上看,这种方法类似于电子邮件收件箱,其中未查看的项目具有以粗体列出的主题标题,而查看的项目具有常规字体粗细。

我的问题与previous stack overflow post类似;但是,该帖子提供了与数据库结构相关的一般答案。我很想知道是否有一种“Rails 方式”来实现我所缺少的这种行为。如果链接的帖子合适,任何人都可以提供有关如何使用 Rails 实现帖子推荐的解决方案的建议吗?

我可以依赖浏览器并使用适当的 CSS 来设置已访问和未访问 URL 的样式,但出于与我的项目相关的其他原因(但不是这个问题,真的)我宁愿有一个依赖 Rails、钩子的解决方案和/或数据库。如果没有直接的 Rails 方法,我也支持其他解决方案(例如,基于 jQuery)。

【问题讨论】:

    标签: jquery ruby-on-rails


    【解决方案1】:

    老实说,link you mentioned 的选项 1 似乎是 最“Rails 方式”的做法。你创建了一个名为View 的模型,它有一个item_id 和一个user_id。我想说最重要的是制作View 资源。

    更新:因此,假设您希望将某个项目标记为已查看,如果用户访问了该项目的 Items#show。这很简单——在Items#show 中,在渲染该页面的视图之前,请执行以下操作:

    View.create(item_id: params[:id], user_id: current_user.id)
    

    如果您担心current_user 未登录或类似情况,您可以在Items#show 上创建before_filter 以使用户登录(如果您要求他在查看之前登录项目)或者只是有条件地创建view

    if current_user
      View.create(item_id: params[:id], user_id: current_user.id)
    end
    

    【讨论】:

    • 我认为你是对的,这就是我链接帖子的原因。不过,我在执行细节上绊倒了。写入 View 资源的最佳位置在哪里?可能是 Item 控制器中的 show 方法?如果是这样,我应该可以轻松访问项目的记录(即item_id),但是如何确保我可以访问用户资源,以便我可以将正确的user_id 写入视图资源?
    • @EliHooten 查看更新后的答案。它假定某种 current_user 辅助方法,例如 Devise 的,但它相当简单。
    • 我认为我需要一个 current_user 助手。没什么大不了。感谢您的回答。根据我的挖掘,这似乎是最好的方法。除非遇到严重问题,否则我将在今天实施并尽快接受。
    • 这个解决方案是正确的。但是,@varatis 的方法将在每次查看页面时创建新记录。因此,如果用户查看页面、离开,然后稍后导航回该页面,则可以为单个页面多次记录“查看”。这可能是理想的行为,但在我的情况下不是。因此,我的Items#show 方法包含对View 数据库的检查,以确定该页面之前是否曾被访问过。如果有,我会增加一个visited_count 作为记录。如果没有,我执行类似于 varatis 提出的View.create。很好的解决方案。谢谢 varatis。
    【解决方案2】:

    在索引中使用的表中添加一个新列并调用它查看

    渲染页面后,将行的查看列设置为 true 或 1

    下次加载页面时,您将检查是否已使用该列查看它,然后显示为斜体,然后渲染页面然后设置新行 - 即所有行为 true

    -- 诀窍是在渲染页面后更新行--

    当您插入新记录时,您会在列视图为 false 的情况下插入它们——未查看

    【讨论】:

    • 这对每个用户来说如何工作呢?两个不同的用户不会修改同一张表吗?例如,用户 A 点击链接 1,用户 B 随后首次加载 index.html.erb,链接 1 以斜体显示(因为用户 A 将其查看属性设置为 true)而不是粗体。也许我缺少一些东西。
    【解决方案3】:

    如果您只想在每个会话的基础上更改链接,您可以这样做...

    如果您真的打算使用 Rails 执行此操作,您可以在会话中存储一个变量来检查页面是否已被访问。像

    session["visited_hash"]["name_of_page_or_whatever"] = true

    然后在索引页面上

    if session["visited_hash"]["name_of_page_or_whatever"] == true
      #render link with special formatting
    else
      #render normally
    

    说实话,我可能会在 CSS 中实现它,但这是在 Rails 中实现它的一种方法。但不能保证它是最有效的。

    【讨论】:

    • 我不会说会话变量是在任何情况下做事的“Rails 方式”..
    • 我完全同意,只是指出如果他想在每个会话的基础上实现此功能,这是一种方法,在数据库中存储标志也不起作用。这个问题没有具体说明他是否需要每次会话。
    猜你喜欢
    • 2023-03-03
    • 2017-06-21
    • 2020-05-16
    • 1970-01-01
    • 2017-10-28
    • 1970-01-01
    • 1970-01-01
    • 2021-10-23
    • 1970-01-01
    相关资源
    最近更新 更多