我有一个小问题:
我正在尝试从控制器1向控制器2发送变量,然后将其发送回控制器1.这是逻辑:
我决定将模型的类型传递给登录屏幕,然后将其传递回新的模型操作。
变量类型通常来自路径,因此在重定向到登录屏幕时,我只是将其传递过来。
businesses_controller.rb
:
before_filter :require_login
def require_login
unless current_user
redirect_to signin_path( :type => params[:type])
end
end
当我被重定向时,变量会被传递到我的网址 - 到目前为止,很好:
/signin?type=ccompany
当我尝试从URL中获取变量并使用其值将成功登录的用户重定向回他试图访问的位置时出现问题:
sessions_controller.rb
:
class SessionsController < ApplicationController
before_filter :initialize_type , :only => [:new , :create]
def new
end
def create
user = User.find_by(email: params[:session][:email].downcase)
if user && user.authenticate(params[:session][:password])
sign_in user
if defined?(@type)
redirect_to send("new_#{@type}_path")
else
redirect_back_or user
end
else
flash.now[:error] = t('sign.invalid')
render 'new'
end
end
def destroy
sign_out
redirect_to root_url
end
private
def initialize_type
@type = params[:type]
end
end
当我将@type
变量放入我的视图中时,其值呈现没有问题。但是当我尝试登录时,这是我得到的错误:
undefined method `new__path' for #<SessionsController:0x007f76189d42f8>
我也试过
redirect_to :controller => "businesses" , :action => "new" , :type => params[:type]
但是类型符号没有键传递。我也试过在那里放一个变量,但仍然不起作用。
到目前为止,它仅在我写下与路径匹配的字符串时才起作用,但这不是我需要的。我需要传递params [:type]哈希的值。我已经将变量的值放在视图中并且它都很好,但是当我尝试将它传递给函数时,它的值会以某种方式'消失'。
我该如何做到这一点?
答案 0 :(得分:4)
问题是:
if defined?(:type)
它总是返回true,因为总是定义一个符号。你想要的是:
if defined?(@type)
然而,这可能会增加“无意识的功能”。对于您的代码,因为nil
在ruby中定义得很好。你应该这样做:
if @type
注:
I need to pass the value of the :type symbol.
- 符号没有价值。变量有值,符号是符号,它是自己的值。
上述情况仍然存在。
您无法将实例变量从一个操作传递到另一个操作。对于每个请求,rails实例化新的控制器实例,并且所有实例变量都将丢失。有很多方法可以通过它。
在表单中创建隐藏字段以保存值。您需要记住,任何互联网用户都可以覆盖其价值,而对互联网的运作方式知之甚少。
在您的新操作中,将值写入会话并在创建操作中读取它。由于会话要么存储在服务器端,要么存储在加密的cookie中,所以任何人都可以使用它进行调整。
答案 1 :(得分:0)
好的,我找到了一个解决方法。它有点笨拙并可能导致安全问题,但它确实有效。我强制变量作为会话参数传递。
我将收到的变量作为隐藏字段放在新的会话表单中:
<%= form_for(:session , url: sessions_path ) do |f| %>
<%= f.label :email , t('session.email') %>
<%= f.text_field :email %>
<%= f.label :password , t('session.password') %>
<%= f.password_field :password%>
<%= f.hidden_field :val , value: @type %>
#@type is set in the before filter as a variable passed from another controller
然后,提交后,我抓住参数并将其放入其位置:
if user && user.authenticate(params[:session][:password])
sign_in user
if defined?(@type)
params.require(:session).permit(:val)
@type = params[:session][:val]
redirect_to send("new_#{@type}_path")
else
redirect_back_or user
end
else
flash.now[:error] = t('sign.invalid')
render 'new'
end
end
现在功能正常。不幸的是,我必须将视图用作传递变量的“管道”。如果有人为此编写辅助方法或更好的解决方法,我会非常高兴。
干杯。