有
这是代码,在session_store.rb
中Rails.application.config.session_store :cookie_store, key: '_blog_session'.
我使用cookie_store。
class HouseController < ApplicationController
def browser
session[:go_controller] = "house"
session[:go_action] = "browser"
@house=House.last
end
class HouseController < ApplicationController
def browser
session[:go_controller] = "house"
session[:go_action] = "browser"
@house=House.last
end
def commercial
session[:current_user_id] = nil
end
def rent
session[:current_user_id] = "chendong"
@house=House.last
end
def search
end
end
在House Controller中,我可以在商业和租借行动中正确设置会话。
class UserController < ApplicationController
def sell
if session[:current_user_id] == nil then
session[:go_controller] = "user"
session[:go_action] = "sell"
redirect_to controller:"user", action:"session"
end
end
但是在另一个控制器(在相同的rails应用程序中),在卖出动作中,session
是一个nilClass。因为当我单击House控制器租借操作来设置session[:current_user_id]
然后单击用户控制器销售操作时,会发生错误
undefined method `[]' for nil:NilClass
在行
if session[:current_user_id] == nil then
答案 0 :(得分:1)
首先关闭。不要在整个控制器中传播您的身份验证逻辑。这是一场等待发生的灾难。例如,不要滥用会话进行分页。主要使用查询参数 - 其次是会话!
class SessionsHelper
def sign_in!(user)
reset_session
session[:current_user_id] = user.id
end
def sign_out!
reset_session
end
# @return [User|Nil]
def current_user
@user ||= User.find(session[:current_user_id])
end
def signed_in?
!current_user.nil?
end
def is_signed_in?(user)
user == current_user
end
end
更好的方法是使用Warden在Rack层上执行此操作。 然后我们想要将这些方法添加到我们所有的控制器中:
class ApplicationController < ActionController::Base
include SessionsHelper
end
我们现在可以重构我们的控制器:
class UserController < ApplicationController
def sell
unless current_user
redirect_to controller: "user", action: "session"
end
end
end
但我们还没有完成!我们应该处理用户未以更好的方式进行身份验证时发生的情况:
class User < ActiveRecord::Base
# ...
class NotAuthenticated < StandardError; end
end
class ApplicationController < ActiveRecord::Base
include SessionsHelper
before_action :authenticate!
rescue_from User::NotAuthenticated, with: :deny_access
private
def authenticate!
raise User::NotAuthenticated unless signed_in?
end
def deny_access
redirect_to controller: "user", action: "session"
end
end
您可能会注意到我们正在破坏所有内容,因为现在每个控制器操作都需要用户登录!但是使用选择退出安全性是一种很好的做法,因为它可以消除您因遗漏而无法保护的路径。
因此,您可以使用skip_before_action :authenticate!, only: [:index]
来允许控制器中的索引操作。
Good Rails应用程序构建在REST上,您可以在其中拥有资源,并且您通常可以使用传统的CRUD操作(显示,索引,创建,编辑,更新,销毁)作用于资源。你很少需要额外的行动。
不要试图把所有东西塞进有限的控制器中! Do-all控制器是一个非常糟糕的模式。
这是RESTful应用布局的一个示例:
Rails.application.routes.draw do
resource :session, only: [:new, :create, :destroy]
resources :users
resources :houses do
resources :bids
end
end
运行$ rake routes
以查看路线布局。