我正在使用Rails 4。
我有子文章嵌入文章。当用户需要在提交之前创建帐户时,我会在会话中存储子文章中的所有表单数据。
以下是我正在使用的内容(subarticles_controller):
def create
if current_user.nil?
session[:subarticle] = params
redirect_to new_user_session_path
end
然后在用户注册后,使用
创建包含存储的参数的子文章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
但是,我遇到了麻烦,保存了创建子文章的article_id。有人能指出我正确的方向吗?
答案 0 :(得分:2)
更好的方法是将访客用户创建的(子)文章保存在数据库中。
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
因此,我们在此向用户提供指向文章编辑页面的链接,他/她可以在登录后“完成”文章。
由于恶意用户可能通过猜测ID并输入编辑网址来“窃取”无人认领的文章,我们会添加一个随机令牌,我们将其与文章一起存储在数据库中并添加到网址中。不是100%万无一失,但至少更好。
要完成这项工作,您还需要在表单中添加一个令牌字段:
<%= form_for(@subarticle) do |f| %>
...
<%= f.hidden_field :token %>
...
<% end %>
您可能想要考虑这个问题的原因是因为会话存储通常是基于内存的,如果您有大量的流量存储会话中的整个params散列将耗尽服务器内存。此外,您应该在登录或退出用户之前重置会话,以避免会话固定。
我们确实遇到了一些问题 - 首先,如果用户(或机器人)从未登录,我们不想累积一堆“无人认领”的文章。最简单的方法是设置一个cron作业在没有关联用户的情况下删除特定年龄的文章。
您还希望在show / index操作中过滤没有用户的任何文章。