Ruby on rails 在具有嵌套资源的会话中存储参数
我使用的是Rails 4 我在文章中嵌套了子文章。当用户需要在提交之前创建帐户时,我将在会话中存储子节中的所有表单数据 以下是我正在使用的(子节\控制器): 然后,在用户注册之后,它使用Ruby on rails 在具有嵌套资源的会话中存储参数,ruby-on-rails,forms,ruby-on-rails-4,parameters,controller,Ruby On Rails,Forms,Ruby On Rails 4,Parameters,Controller,我使用的是Rails 4 我在文章中嵌套了子文章。当用户需要在提交之前创建帐户时,我将在会话中存储子节中的所有表单数据 以下是我正在使用的(子节\控制器): 然后,在用户注册之后,它使用 if session[:subarticle].present? @subarticle = current_user.subarticles.create(session[:subarticle]["subarticle"]) session[:subarticle] = nil flash[
if session[:subarticle].present?
@subarticle = current_user.subarticles.create(session[:subarticle]["subarticle"])
session[:subarticle] = nil
flash[:notice] = "Awesome, you are logged in and your answer is undergoing review."
edit_user_registration_path
end
但是,我在保存创建子篇的文章_id时遇到了问题。有人能给我指出做这件事的正确方向吗 更好的方法是将来宾用户创建的(子)文章保存在数据库中
class SubArticlesController < ApplicationController
before_action :set_article, only: [:show, :edit, :update, :destroy]
# ...
def create
@subarticle = Article.new(article_params) do |a|
if current_user
a.user = current_user
else
a.token = SecureRandom.hex
end
end
if @subarticle.save
if @subarticle.user
redirect_to @subarticle
else
session[:after_sign_in_path] = edit_article_path(@subarticle, token: @subarticle.token)
redirect_to new_user_session_path, notice: 'Please sign in to finalize your article.'
end
else
render :new
end
end
def edit
if @subarticle.user.nil? && @subarticle.token != params[:token]
redirect_to root_path, alert: 'You are not authorized.'
end
flash[:notice] = 'Please press save again to publish your post.' unless @subarticle.user
render :edit
end
def update
# The @subarticle.token should be included in the edit form
unless @subarticle.user && @subarticle.token == params[:sub_article][:token]
# let the current user claim the article
@subarticle.user = current_user
end
if @subarticle.update(article_params)
redirect_to @subarticle
else
render :edit
end
end
private
def set_article
@subarticle = Article.find(params[:id])
end
def sub_article_params
params.require(:sub_article).permit(...)
end
end
class SubticlesController
因此,我们在这里为用户提供了一个指向文章编辑页面的链接,用户可以在登录后“完成”文章
由于恶意用户可能通过猜测id并输入编辑url来“窃取”无人认领的文章,因此我们添加了一个随机令牌,将其与文章一起存储在数据库中并添加到url中。不是100%万无一失,但至少更好
要实现此功能,您还需要在表单中添加一个令牌字段:
<%= form_for(@subarticle) do |f| %>
...
<%= f.hidden_field :token %>
...
<% end %>
...
...
<> P>您可能想考虑这一点是因为会话存储通常是基于内存的,并且如果有大量的流量存储,会话中的整个PARAMS散列将耗尽服务器内存。此外,您还应在用户登录或注销之前重置会话,以避免会话固定
不过,我们确实有一些问题——首先,如果用户(或机器人)从未登录,我们不想积累一堆“无人认领”的文章。最简单的方法是设置一个cron作业,在没有关联用户的情况下删除超过一定年龄的文章
您还希望从show/index操作中筛选没有用户的任何文章是否将(父)项保存到数据库中?当然,如果不使用HTTPS,令牌在URL中仍然容易受到中间人攻击的影响。不过,这可能是“足够好”的安全性。非常感谢您的深入回答和推荐更好的解决方案。我很可能会走这条路,但是如果我想继续我的路,我怎么才能把文章ID保存在那里呢?我的目标是稍后调用
subtitle.article.title
,但我收到一个错误,因为它找不到文章。此外,我不必担心有人偷了一篇文章,因为用户在提交后无法编辑文章(cancancan)。应该说得更清楚。再次感谢你@max您必须先将其保存到数据库才能获得id-ActiveRecord中的id只是自动递增的数据库列。
<%= form_for(@subarticle) do |f| %>
...
<%= f.hidden_field :token %>
...
<% end %>