为什么 yield 不将结果传递给块 (Rails)?
Why is yield not passing the result to block (Rails)?
我知道有几个 SO 问题以及关于在 Rails 中使用 yield
的在线文章。但是我仍然无法理解我下面的代码有什么问题,如果有任何建议,我将不胜感激。
在我的应用程序中,我有:
A controller
将数据传递给 command
class 的 run
方法,returns 基于请求状态根据 Command.run
(true
/false
)
的结果
A command
class 处理流程的实际内容,然后 yields
true
如果成功,或者 false
如果失败了
不过,command
class 似乎没能 yield
结果到我的 controller
。根据我 运行 测试时的错误消息,我在 controller
中的块似乎没有被识别为块:
# If I use "yield result":
LocalJumpError: no block given (yield)
# If I use "yield result if block_given?":
# (This is because I have "assert_response :success" in my tests)
Expected response to be a <2XX: success>, but was a <400: Bad Request>
我应该如何重写块(下面控制器中的 do ... end
部分)以便 yield
正常工作?或者,如果问题出在其他地方,我做错了什么?
我在下面提供了我的代码的简化版本。提前致谢!
# controller
def create
Command.run(params) do
render json: { message: 'Successfully processed request' }
return
end
render json: { message: 'Encountered an error' }, status: :bad_request
end
# command class
def run(params)
# Do some stuff, then send HTTP request
# "result" below returns true or false
result = send_http_request.parsed_response == 'ok'
yield result
end
def self.run(params)
new.run(params)
end
注意:如果我在控制器中使用 if true... else...
而不是块,并且只是 return
布尔结果而不是 yielding
,则此代码有效。但在这里我想知道如何使 yield
工作。
在您的控制器中,您需要为结果设置一个变量。
def create
Command.run(params) do |result|
if result
render json: { message: 'Successfully processed request' }, status: :success
else
render json: { message: 'Encountered an error' }, status: :bad_request
end
return
end
render json: { message: 'Encountered an error' }, status: :bad_request
end
(编辑)
此外,您正在调用调用实例方法的 class 方法。您必须将块从调用代码传递到您正在调用的实例方法。
def self.run(params, &block)
new.run(params, &block)
end
编辑:啊,所以你有一个 class 方法 run
和实例方法 run
.
要么按照 Marlin 的建议进行操作,要么显式地将块从 class 方法提供给实例方法。
或者只使用我最初建议的 class 方法(它不
在你的情况下似乎有任何理由实例化 Command
):
def self.run(params, &block)
result = send_http_request.parsed_response == 'ok'
block.yield(result)
end
我知道有几个 SO 问题以及关于在 Rails 中使用 yield
的在线文章。但是我仍然无法理解我下面的代码有什么问题,如果有任何建议,我将不胜感激。
在我的应用程序中,我有:
A
controller
将数据传递给command
class 的run
方法,returns 基于请求状态根据Command.run
(true
/false
) 的结果
A
command
class 处理流程的实际内容,然后yields
true
如果成功,或者false
如果失败了
不过,command
class 似乎没能 yield
结果到我的 controller
。根据我 运行 测试时的错误消息,我在 controller
中的块似乎没有被识别为块:
# If I use "yield result":
LocalJumpError: no block given (yield)
# If I use "yield result if block_given?":
# (This is because I have "assert_response :success" in my tests)
Expected response to be a <2XX: success>, but was a <400: Bad Request>
我应该如何重写块(下面控制器中的 do ... end
部分)以便 yield
正常工作?或者,如果问题出在其他地方,我做错了什么?
我在下面提供了我的代码的简化版本。提前致谢!
# controller
def create
Command.run(params) do
render json: { message: 'Successfully processed request' }
return
end
render json: { message: 'Encountered an error' }, status: :bad_request
end
# command class
def run(params)
# Do some stuff, then send HTTP request
# "result" below returns true or false
result = send_http_request.parsed_response == 'ok'
yield result
end
def self.run(params)
new.run(params)
end
注意:如果我在控制器中使用 if true... else...
而不是块,并且只是 return
布尔结果而不是 yielding
,则此代码有效。但在这里我想知道如何使 yield
工作。
在您的控制器中,您需要为结果设置一个变量。
def create
Command.run(params) do |result|
if result
render json: { message: 'Successfully processed request' }, status: :success
else
render json: { message: 'Encountered an error' }, status: :bad_request
end
return
end
render json: { message: 'Encountered an error' }, status: :bad_request
end
(编辑)
此外,您正在调用调用实例方法的 class 方法。您必须将块从调用代码传递到您正在调用的实例方法。
def self.run(params, &block)
new.run(params, &block)
end
编辑:啊,所以你有一个 class 方法 run
和实例方法 run
.
要么按照 Marlin 的建议进行操作,要么显式地将块从 class 方法提供给实例方法。
或者只使用我最初建议的 class 方法(它不 在你的情况下似乎有任何理由实例化
Command
):def self.run(params, &block) result = send_http_request.parsed_response == 'ok' block.yield(result) end