如何在会话变量中存储find_by_sql_results

时间:2011-12-04 05:29:12

标签: ruby-on-rails ruby

这是我的控制器代码,用于检查用户的登录详细信息

def validateLogin
  @email = params[:userEmail1]
  @pass = params[:userPassword1]

  if params[:userEmail1] != nil
    valid_user = Userprofile.find_by_sql(["select * from userprofiles where userEmail=? and userPassword=?", @email, @pass])
    if valid_user.count > 0
      session[:email] = @email
      session[:uid] = valid_user.id
      session[:userType] = valid_user.userType # usertype is a column in userprofiles table
      # But here i am not receiving the usertype  it gives error that undefined variable usertype.
      redirect_to "/userhomes/"
    else
      flash[:message] = "Either email or password is incorrect"
      redirect_to '/'
    end
else
  flash[:message]="Fields can not be blank"
  render :action=>'defaults'
end

请帮忙

session[:userType] = valid_user.userType
# Error: (usertype is a column in userprofiles table)

但是在这里我没有收到usertype,它给出了未定义变量usertype的错误。

1 个答案:

答案 0 :(得分:2)

您看到此错误是因为您收到了来自find_by_sql的对象数组。您甚至可以在if子句中检查数组的大小。

从您的代码中我认为您只期望一个返回的对象。但你仍然需要从数组中得到它:

profiles = Userprofile.find_by_sql(["select * from userprofiles where userEmail=? and userPassword=?", @email, @pass])
if profiles.count > 0
  user_profile = profiles[0]
  #... your other stuff
end

另一个更好地使用Rails习惯用法,特别是ActiveRecord的变体本身被用来让它自己构造SQL,这通常更安全,更不容易出错和缓存。

您没有编写正在使用的Rails版本,但对于Rails 2.3.x,它看起来像这样

user_profile = Userprofile.first(:conditions => {:userEmail => @email, :userPassword => @pass})

对于Rails 3.x,它看起来像这样:

user_profile = Userprofile.where(:userEmail => @email, :userPassword => @pass).first

两种变体都希望您拥有一个名为Userprofile的模型,您通常需要这种模型来有效地处理Rails中的数据库对象。这两个查询的作用是从查询返回的第一行创建一个新的模型实例(这就是first的作用)。

通常,您应该在互联网上获得一本书或一些指南,并学习如何正确使用ActivRecord。请注意,在Rails 2.3和Rails 3之间API已经发生了严重的变化,因此请务必使用指南来了解您的实际Rails版本。

作为最终建议,您不应在会话中存储实际的ActiveRecord对象。它们需要在存储上序列化并在访问时反序列化。是什么让它变得困难(或者无法跟踪对象引用。

此外,Rails默认使用cookie会话存储,这意味着整个会话数据存储在客户端的cookie中。其中的数据完全准备好可以访问cookie的任何人,因为它只是签名以限制对数据的篡改,但它没有加密。因此,在您的情况下,任何人都可以准备好(未加密的)密码。

您应该存储它的id而不是存储模型对象,而是从每个请求中获取数据库中的实际(和最新)对象。这样更容易,可以避免缓存不一致(如果用户更改密码会发生什么),并且可能比在每次请求时从客户端传输大量会话cookie更快。