我的路线与/edit_account => accounts#edit
相匹配,因为如果帐户ID未使用当前用户ID且account#edit
方法与{{1}共享}}
/accounts/[:id]/edit
我遇到的问题是class AccountController < ApplicationController
...
def edit
# This doesn't work:
params = retrieve_id_if_missing(params)
# This works:
# aHash = params
# params = retrieve_id_if_missing(aHash)
end
def retrieve_id_if_missing(params)
# raise params.inpect => returns nil at this point
if params[:id].nil? and !logged_in?
redirect_to root_path
else params[:id].nil?
params[:id] = current_user.id
end
params
end
end
,当传递给类方法时,params
正在变为retrieve_id_if_missing
。但是,如果我将nil
分配给另一个变量。例如,params
,在将其传递给aHash
之前,它将包含预期数据retrieve_id_if_missing
。
我已经尝试寻找原因但是做得很短,有人可以向我解释为什么会发生这种情况吗?
答案 0 :(得分:2)
你试过吗
class AccountController < ApplicationController
...
def edit
retrieve_id_if_missing
end
def retrieve_id_if_missing()
if params[:id].nil? and !logged_in?
redirect_to root_path
else params[:id].nil?
params[:id] = current_user.id
end
params
end
end
我很确定params将在该方法的范围内。
无论如何,请查看宝石设计。它应该拥有你想要的一切和更多
有了设计,你可以使用
before_filer :authenticate_user!
位于控制器的顶部
答案 1 :(得分:0)
虽然我无法回答为什么你的params对象会被提供的代码覆盖,但这里有一些想法。
class AccountController < ApplicationController
before_filter :retrieve_id_if_missing, only: :edit
def edit
# You'll find params[:id] prepopulated if it comes here,
# else the request has been redirect
end
protected
# There should be no need to pass the params object around, it should be accessible everywhere
def retrieve_id_if_missing
if logged_in?
params[:id] ||= current_user.id # conditional assignment will only happen if params[:id] is nil
end
# Redirect to root if params[:id] is still blank,
# i.e. user is not logged in and :id was not provided through route
if params[:id].blank?
flash[:alert] = 'You need to be logged in to access this resource.'
return redirect_to root_url # early return!
end
end
end
答案 2 :(得分:0)
Ruby解释器将params
视为局部变量,并在看到赋值时使用nil
初始化它。这在执行retrieve_id_if_missing
之前发生。
这就是为什么在调用方法之前显式地为局部变量赋值避免错误的原因,因为Ruby的nil
初始化没有发生。
以下示例说明了这一点:
示例#1
def foo(bar)
puts "foo bar: #{bar.class}"
end
bar = foo(bar) # => nil
puts "bar: #{bar.class}"
# Outputs:
# foo bar: NilClass
# bar: bar: NilClass
示例#2
a = a # => nil
puts "a: #{a.class}"
# Outputs:
# a: NilClass
示例#3
a = 123 if a # => nil
puts "a: #{a.class}"
# Outputs:
# a: NilClass
参考文献:
Ruby解释器在看到一个局部变量时用nil初始化 转让给它。它在执行之前初始化局部变量 赋值表达式,甚至在无法访问赋值时 (如下例所示)。这意味着您的代码初始化为nil 然后表达式a = nil将评估为右手值。
a = 1如果是假的a.nil? #=&gt; true第一个赋值表达式不是 执行,但是a用nil初始化。
Ruby: method inexplicably overwritten and set to nil
这是另一个例子:
a = 123,如果#=&gt;没有#=&gt;没有我们不能说是否a 因为我们从未设置过,但Ruby看到a = 123并初始化a, 然后到达如果a点是零
我真的认为这是翻译的怪癖。加里伯恩哈特 在wat(https://www.destroyallsoftware.com/talks/wat)取笑它 a = a