通过登录保持表单输入

我有这个应用程序,用户可以写一个学校的评论。 用户必须使用Facebook登录才能保存评论。 问题是如果用户未签名并撰写评论,然后使用Facebook登录他们必须再次撰写相同的评论。

我试图通过将评论数据表格存储在会话中来解决这个问题,但我不能让它工作。

这样做的正确方法是什么?

ReviewForm:

    "btn" %>   "btn" %>   

ReviewController

 class ReviewsController  review, :school_id => school, :user_id => current_user, :rating => rating) end private def signed_in? !current_user.nil? end def signed_in_user unless signed_in? # Save review data into sessions session[:school] = School.find(params[:school_id]) session[:review] = params[:review] session[:rating] = params[:rating] # Login the user to facebook redirect_to "/auth/facebook" # After login save review data for user save_review(session[:school], session[:review], session[:rating]) end end end 

您应该将审阅保存在创建会话操作中(不包括在您的问题中)。 假设您正在使用omniauth,您可以在处理回调的操作上添加一些内容

 # review controller def signed_in_user unless signed_in? # Save review data into sessions session[:school] = School.find(params[:school_id]) session[:review] = params[:review] session[:rating] = params[:rating] # Login the user to facebook redirect_to "/auth/facebook" end end # callback to login the user def handle_callback # do your thing here to login the user # once you have the user logged in if signed_in? if session[:school] && session[:review] && session[:rating] # or just 1 check Review.create( content: session.delete(:review), school_id: session.delete(:school), user_id: current_user.id, rating: session.delete(:rating) ) #redirect_to somewhere end end end 

我使用了删除,因此会话将被清除这些值。

更新:因为您正在使用会话控制器

 class SessionsController < ApplicationController def create if user = User.from_omniauth(env["omniauth.auth"]) session[:user_id] = user.id if session[:school] && session[:review] && session[:rating] # or just 1 check review = Review.new review.content = session.delete(:review) review.school_id = session.delete(:school) review.user_id = user.id review.rating = session.delete(:rating) review.save end end redirect_to :back end 

我的理解是,除了像用户令牌之类的非常小的东西之外,在会话中存储东西并不是“The Rails Way”。你可以在Obie Fernandez的The Rails 3 Way中阅读更多关于这个想法的内容。

我建议您从一开始就将评论存储在数据库中,并且只有在评论与Facebook认证用户连接后才会“复查”评论。 如果您对如何实现这一目标有任何好奇心,我很乐意详细说明。

编辑 :这里有一些示例代码。 首先,我会将用户与评论相关联,以实现“永久”存储。 你可以只在review表中添加一个user_id ,但大部分时间它可能都是null ,这对我来说似乎很草率:

 $ rails g model UserReview review_id:references, user_id:references 

然后我将创建一个带有review_iduser_session_tokenuser_session_review表。 这是用于“临时”存储:

 $ rails g model UserSessionReview review_id:integer, user_session_token:string 

然后,当用户注册时,将任何“临时”评论与该用户关联:

 class User has_many :user_reviews has_many :reviews, through: :user_reviews has_many :user_session_reviews def associate_reviews_from_token(user_session_token) temp_reviews = UserSessionReview.find_all_by_user_session_token(user_session_token) temp_reviews.each do |temp_review| user_reviews.create!(review_id: temp_review.review_id) temp_review.destroy end end end 

所以在你的控制器中,你可能会这样做

 class UsersController < ApplicationController def create # some stuff @user.associate_reviews_from_token(cookies[:user_session_token]) end end 

你当然必须稍微阅读一下这些内容,但我认为应该让你去。

编辑2 :要删除旧的废弃评论,我会做这样的事情:

 class UserSessionReview scope :old, -> { where('created_at < ?', Time.zone.now - 1.month) } end 

然后,在一个cron工作:

 UserSessionReview.old.destroy_all