Rails5在会话中的任何位置访问配置文件数据,而无需每次查询数据库



我有一个用户配置文件(带有名称、徽标、about_me),它是在用户创建(使用Devise)后创建的。配置文件表使用user_id作为主键。

现在,我希望每当用户创建/更新帖子时,在填写表单时,都会从概要文件中获取一些详细信息,因此概要文件数据或@profile在帖子表单中可用,因为我无法在表单中公开我的模型。要在create和#update中设置post.myname属性,我正在这样做:

@myprofile = Profile.find_by_user_id(current_user)
write_attribute(:myname, @myprofile.name)

我从各种来源了解到,但给定的4的最佳解决方案是什么?如果有人能用简单的代码支持我,因为我不想做一些广泛的事情?提前谢谢。

1) 表单隐藏字段-类似于在#edit中的hash中获取如上所述的配置文件数据,然后在#update中传递表单和访问字段,但这样我们将分别传递每个字段。可以传递一个@myprofile吗?

2) 会话-我觉得如果配置文件数据存储在会话中,并且有人更新了配置文件,那么更新后的数据将无法在该会话中使用。所以不确定这是否合理。

3) 缓存-简单的方法?

4) 多态配置文件--尝试过,但我没有得到相关的例子。我一直纠结于什么是可评测的id和类型,以及如何在代码中使用它们。

如果您的Profile和User模型之间有一对一的关系,最简单的解决方案是完全删除Profile模型并将其字段移到User模型中。

Devise已经查询了数据库以获得current_user对象。所以,你的例子是这样的:

write_attribute(:myname, current_user.name)

它不会访问数据库(在Devise检索到current_user对象之后)。


如果你被迫保留Profile模型,在查看你的四个场景时。。。

  1. 可以使用会话变量。类似于:

    session[:profile_name] ||= @myprofile.name
    

    这将进入控制器操作。

    这里的技巧是,如果概要文件得到更新,您将希望重新定义每个相关的会话变量。由于您无法访问模型中的会话,因此最好在控制器中执行该操作。所以,不漂亮,但它可以工作。

  2. 您还可以使用低级缓存,并将配置文件关系保存在用户上。一般来说,您可以在用户模型中使用这样的方法:

    def profile_cached
    Rails.cache.fetch(['Profile', profile.id]) do
    profile
    end
    end
    

    在这里,您也必须知道缓存何时过期。这种方法的好处是,您可以将这些代码放在模型中,这意味着您可以在回调中挂起它的过期时间。

    请参阅"使用Rails缓存"中的更多内容。

我会避免隐藏字段,我不确定多态关系如何解决你不访问数据库的问题。因此,#2和#3是可选的,但如果你能将这两个模型合并为一个,那应该会简化它

最新更新