【问题标题】:Rails: elsif && conditional statement in controller action not workingRails:控制器操作中的 elsif && 条件语句不起作用
【发布时间】:2019-05-31 05:08:27
【问题描述】:

我正在制作一个基于 Ryan Bates 的 #217 Multistep Forms 教程的多步骤表单。我需要在表单内实现条件导航,事情变得相当复杂。

表单内的导航工作正常,但我的控制器中的条件与提交相关。

def create
  @order.current_step = session[:order_step]
  if @order.valid?
    if params[:back_button]
      @order.previous_step
    elsif params[:back_button_wiretransfer]
      @order.payment_options_step
    elsif params[:back_button_credit_card]
      @order.creditcard_options_step
    elsif @order.thirdlast_step? && params[:commit] == 'Wiretransfer'
      @order.payment = nil
      @order.payment = 'Wiretransfer'
      @order.confirmation_step
    elsif @order.thirdlast_step? && params[:commit] == 'Credit card'
      @order.next_step
    elsif @order.secondlast_step?
      @order.payment = nil
      @order.payment = 'Credit card'
      @order.next_step
    elsif @order.last_step? && @order.payment = 'Wiretransfer'
      ...
    elsif @order.last_step? && @order.payment = 'Credit card'
      ...
    else
      @order.next_step
    end
    session[:order_step] = @order.current_step
  end
  if @order.new_record?
    render "new"
  else
    ...
  end
end

当前控制器无法使用@order.payment = 'wiretransfer'@order.payment = 'credit card' 应用最后两个 elsif 条件。

所有其他条件都正常,但是当我通过信用卡部分结账时,电汇部分被执行。

当我使用时:

elsif @order.last_step? && @order.payment == 'Wiretransfer'
  ...
elsif @order.last_step? && @order.payment = 'Credit card'
  ...

“信用卡”有效,但“电汇”无效。由于我在表单的最后一步显示了支付属性,因此我知道它在该步骤中仍然存在,尽管它尚未保存到数据库中。

我做错了什么?我发现有时我必须使用=,而有时我必须使用==,但我并不清楚其合理性。

在视图中我必须使用==(比较),例如:

<% elsif @order.last_step? && @order.payment == "Credit card" %>

触发正确的 div。

在控制器中两个条件

elsif @order.thirdlast_step? && params[:commit] == 'Wiretransfer' 
elsif @order.thirdlast_step? && params[:commit] == 'Credit card'

仅与== 一起使用,而所有其他仅与= 一起使用。我开始在控制器中只使用==,但是当我这样做时,什么都没有被执行并且新的被渲染。

提前谢谢你!

【问题讨论】:

  • 看到像thirdlast_step? 这样的方法有点令人担忧。也许有更好的表达方式,比如将其转向case 以分解步数和:commit 参数。
  • 是的,我确实很担心;0)。我还没有重构,但只添加了两个步骤来查看条件导航是否可以工作。
  • 请注意,本教程确实看起来过于复杂并且有点过时(Rails 3.2?),所以请谨慎对待它的建议。
  • 查看这段代码我不确定这是最好的方法。您最好保存一条设置了某种“待处理”或“不完整”标志的记录,并在每个请求之间向前推进,并根据需要添加数据。最后一步将标志关闭,使其“真实”。这种方法似乎是滚雪球方法,其中参数在视图中累积并每次来回踢。这通常比拥有一张包含(可能)不完整记录的表要混乱得多,您需要将其保持在范围之外并且在变为现实之前是不可见的。
  • 感谢您的建议,我会珍惜的。我更改了条件以查询按钮,现在它可以工作了。因为这是最后一块,我想让一切都先运行。现在我将开始更彻底地完善和重构您的建议。再次感谢!

标签: ruby-on-rails ruby ruby-on-rails-3 conditional


【解决方案1】:

在这两种情况下你都应该使用==

elsif @order.last_step? && @order.payment == 'Wiretransfer'
  ...
elsif @order.last_step? && @order.payment == 'Credit card'
  ...

= 为变量赋值,而== 检查两个值/变量是否相等。

= 返回一个赋值,在这两种情况下它不是 nil,它被评估为事实 - 这就是为什么当你有:

elsif @order.last_step? && @order.payment = 'Wiretransfer'

下一个elsif 永远不会被调用。

值得一读:

【讨论】:

  • 这种差异可能看起来很小,但由于差异很大,因此程序员通常需要注意这一特定细节。
  • 感谢您的反馈。事实上,我从== 开始,但不知何故,条件的第二部分没有执行,而是呈现了一个新视图。
  • &amp;&amp; 使用一种称为“短路评估”的方法,这意味着如果表达式的左侧部分返回 false,则无需评估表达式的右侧部分。我会确保@order.last_step?true,否则永远不会检查@order.payment
  • 感谢您的回复!在我的最后一个视图中,相同的条件 elsif @order.last_step? &amp;&amp; @order.payment == "Wiretransfer" 确实有效。只有控制器语句不知何故不起作用...
  • 谢谢大家,我学到了很多!我不得不更改语句并使用 params[:somebutton] 现在它可以工作,我可以开始重构和改进。我会接受这个答案......虽然它没有完全解决我的问题,但它果断地为我指明了正确的方向,并且是关于这种混乱最明智的说法;0)。我认为以某种方式不可能在控制器操作的条件语句中查询在同一操作中创建但尚未写入数据库的属性...
猜你喜欢
  • 2016-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-08
  • 2011-12-04
  • 2012-08-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多